KMP(Kotlin Multiplatform)发布Web版本乱码

一、背景

最近用KMP尝试运行在Android、iOS、desktop都成功了,网络数据访问也正常。

可是当运行wasmJs的时候遇到了2个较大的问题。

  1. 中文字体出现乱码。

  2. 出现了跨域问题。

首先贴一下每个平台的运行截图:

Android

iOS

Desktop

二、问题

当web跑起来的时候,令人震惊的事情发生了

KMP(Kotlin Multiplatform)发布Web版本乱码_第1张图片

2.1 乱码问题

除了数字,其他的文字都不显示。猜测是字体的问题,wasmJs可能还没有内置默认字体,导致字体显示乱码。

2.2 跨域问题

观察浏览器控制台api访问的数据都成功拿到,但所有图片资源被跨域拦截。

目前没有找到关于wasm提供像Vue一样的本地代理跨域的方案。

三、解决

2.1 乱码问题解决方案

既然是字体导致的,那就找一个免费字体内置进去,尝试后,果然有效,效果如下

KMP(Kotlin Multiplatform)发布Web版本乱码_第2张图片

只需要在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中,把所有字体都换成自定义的字体。

2.2 跨域问题解决方案

跨域问题比较好解决,最快和彻底的方式就是告诉服务端或者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保持一致。

你可能感兴趣的:(kotlin,前端,开发语言)