Android-WebView加載本地Html当娱,不能識別類型為module的JS
背景
最近在做Android開發(fā)時(shí)遇到一個(gè)問題,就是在Android O上加載本地網(wǎng)頁時(shí)出現(xiàn)無法顯示的問題斧蜕,并且在控制臺看到有相關(guān)錯(cuò)誤輸出,如下:
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.
當(dāng)看到這個(gè)錯(cuò)誤時(shí)砚偶,就想到是本地的JS無法被WebView識別批销,果然,查看到本地JS類型為module染坯。在一些高版本Android上這是可以被識別出來的均芽,但是在一些低版本上就無法識別。因此单鹿,首先想到的就是采用Webkit提供的WebViewAssetLoader來解決該問題掀宋。
具體解決步驟
WebViewAssetLoader: 用于給WebView提供資源加載的,在WebViewClient中的方法shouldInterceptRequest中調(diào)用,如下:
override fun shouldInterceptRequest(
view: WebView?,
request: WebResourceRequest
): WebResourceResponse? {
return webviewAssetLoader.shouldInterceptRequest(view, request)
}
但是劲妙,光這樣是不能解決問題的湃鹊,還需要配置WebViewAssetLoader,需要配置相關(guān)參數(shù)镣奋,如下:
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币呵,那是因?yàn)閃ebViewAssetLoader是為Http(s)在線網(wǎng)頁提供的本地資源的加載,但是這里我們的網(wǎng)頁也是本地的侨颈,因此我們就需要把自己的網(wǎng)頁也包裝成一個(gè)在線網(wǎng)頁富雅,因此需要這個(gè)包裝后的網(wǎng)頁的域名與設(shè)置的域名一致,我們的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的匹配處理,然后就可以得到我們設(shè)置的本地資源了鬼癣,因?yàn)槲覀冞€要處理JS的MimeType陶贼,還需要通過文件后綴判斷得到JS文件,并為其設(shè)置新的類型:text/javascript 待秃。
最終拜秧,我們的網(wǎng)頁就可以正常顯示了,完美章郁!