最近用KMP尝试运行在Android、iOS、desktop都成功了,网络数据访问也正常。
可是当运行wasmJs的时候遇到了2个较大的问题。
中文字体出现乱码。
出现了跨域问题。
首先贴一下每个平台的运行截图:
当web跑起来的时候,令人震惊的事情发生了
除了数字,其他的文字都不显示。猜测是字体的问题,wasmJs可能还没有内置默认字体,导致字体显示乱码。
观察浏览器控制台api访问的数据都成功拿到,但所有图片资源被跨域拦截。
目前没有找到关于wasm提供像Vue一样的本地代理跨域的方案。
既然是字体导致的,那就找一个免费字体内置进去,尝试后,果然有效,效果如下
只需要在wasmJsMain中的main入口处,添加主题默认字体即可。
fun main() {
ComposeViewport(document.body!!) {
MaterialTheme(typography = HTypography()) {
App()
}
}
}
使用MeterialTheme主题,赋值参数typography,值为自定义集成Typography的函数,如下
@Composable
fun HTypography(): Typography {
val defaultFontFamily = FontFamily(
org.jetbrains.compose.resources.Font(
Res.font.DouyinSansBold
)
)
return Typography(
bodySmall = MaterialTheme.typography.bodySmall.copy(
fontFamily = defaultFontFamily,
),
bodyMedium = MaterialTheme.typography.bodyMedium.copy(
fontFamily = defaultFontFamily,
),
bodyLarge = MaterialTheme.typography.bodyLarge.copy(
fontFamily = defaultFontFamily,
//fontWeight = FontWeight.Bold,
),
titleSmall = MaterialTheme.typography.titleSmall.copy(
fontFamily = defaultFontFamily,
),
titleMedium = MaterialTheme.typography.titleMedium.copy(
fontFamily = defaultFontFamily,
),
titleLarge = MaterialTheme.typography.titleLarge.copy(
fontFamily = defaultFontFamily,
),
headlineSmall = MaterialTheme.typography.headlineSmall.copy(
fontFamily = defaultFontFamily,
),
headlineMedium = MaterialTheme.typography.headlineMedium.copy(
fontFamily = defaultFontFamily,
),
headlineLarge = MaterialTheme.typography.headlineLarge.copy(
fontFamily = defaultFontFamily,
),
)
}
声明FontFamily字体,其中DouyinSansBold为网络上找的免费字体,放入composeApp/commonMain/composeResources/font文件夹。
在返回的Typography中,把所有字体都换成自定义的字体。
跨域问题比较好解决,最快和彻底的方式就是告诉服务端或者API网关管理人员,把要访问的IP配置进去。如果是开发测试环境没有很强的安全性要求,只需要在服务Nginx添加Access-Control-Allow-Origin "*"即可。如果是直接访问的Java服务,在SpringBoot上也可以加跨域的注解。
本次使用的方式不借助他人,自己搞定。方式也是通过Nginx来实现。
在本地通过docker搭建Nginx服务做中转,详细参考另一篇文章《本地Nginx解决跨域问题》。
在项目中,把所有Wasm平台图片的访问中转到localhost下,因为nginx的配置端口是80,只需要把图片url路径添加localhost即可访问到本地nginx服务,由nginx服务反向代理资源。
fun String.proxyAliOss(): String {
return if (getPlatform().type.contentEquals("Wasm")) {
this.replaceFirst(
"https://", "http://localhost/"
)
} else {
this
}
}
如此成功显示图片资源,效果上和Android、iOS、Desktop保持一致。