美文网首页
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