美文网首页
Android-WebView加载本地Html,不能识别类型为m

Android-WebView加载本地Html,不能识别类型为m

作者: Cosecant | 来源:发表于2023-02-06 14:20 被阅读0次

Android-WebView加载本地Html,不能识别类型为module的JS

背景

最近在做Android开发时遇到一个问题,就是在Android O上加载本地网页时出现无法显示的问题,并且在控制台看到有相关错误输出,如下:

Failed to load module script: The server responded with a non-JavaScript MIME type of "". Strict MIME type checking is enforced for module scripts per HTML spec.

当看到这个错误时,就想到是本地的JS无法被WebView识别,果然,查看到本地JS类型为module。在一些高版本Android上这是可以被识别出来的,但是在一些低版本上就无法识别。因此,首先想到的就是采用Webkit提供的WebViewAssetLoader来解决该问题。

具体解决步骤

WebViewAssetLoader: 用于给WebView提供资源加载的,在WebViewClient中的方法shouldInterceptRequest中调用,如下:

    override fun shouldInterceptRequest(
        view: WebView?,
        request: WebResourceRequest
    ): WebResourceResponse? {
        return webviewAssetLoader.shouldInterceptRequest(view, request)
}

但是,光这样是不能解决问题的,还需要配置WebViewAssetLoader,需要配置相关参数,如下:

 private val webViewAssetLoader by lazy {
        val fileRegex = "^file://".toRegex()
        val httpRegex = "^http(s)?://".toRegex()
        val resourcePath = HybridVersionManager.currentTemplatePath
        WebViewAssetLoader.Builder().addPathHandler(
                resourcePath.replace(fileRegex, "").plus(File.separatorChar),
                when (resourcePath) {
                    HybridVersionManager.DefaultHybridPath ->
                        WebViewAssetLoader.AssetsPathHandler(context)
                    else -> WebViewAssetLoader.InternalStoragePathHandler(
                        context,
                        File(resourcePath.replace(fileRegex, ""))
                    )
                }
            )
            .setHttpAllowed(true)
            .setDomain(BuildConfig.BaseUrl.replace(httpRegex, ""))
            .build()
    }

这里讲一下为什么要配置HttpAllowed和Domain,那是因为WebViewAssetLoader是为Http(s)在线网页提供的本地资源的加载,但是这里我们的网页也是本地的,因此我们就需要把自己的网页也包装成一个在线网页,因此需要这个包装后的网页的域名与设置的域名一致,我们的shouldInterceptRequest也还需要做一下修改,如下:

    override fun shouldInterceptRequest(
        view: WebView?,
        request: WebResourceRequest
    ): WebResourceResponse? {
        val newUrl = request.url?.run {
            if (scheme == "file")
                Uri.parse(
                    toString().replace(
                        "^file://".toRegex(),
                        BuildConfig.BaseUrl
                    )
                )
            else this
        } ?: return super.shouldInterceptRequest(view, request)
        return webViewAssetLoader.shouldInterceptRequest(newUrl)?.apply {
            if (request.url?.path?.endsWith(".js", true) == true)
                mimeType = "text/javascript"
        }
    }

以上代码,通过包装file,然后交给WebViewAssetLoader处理,通过Loader的匹配处理,然后就可以得到我们设置的本地资源了,因为我们还要处理JS的MimeType,还需要通过文件后缀判断得到JS文件,并为其设置新的类型:text/javascript 。

最终,我们的网页就可以正常显示了,完美!

相关文章

网友评论

      本文标题:Android-WebView加载本地Html,不能识别类型为m

      本文链接:https://www.haomeiwen.com/subject/hbjtkdtx.html