我正在 Android 中开发和应用程序,其中有一段使用 javascript 和 python 编写的 Transcrypt (这几乎等同于说我正在直接用 javascript 开发该部分,但我无法完全控制事物的制作方式)。 Android 在带有 WebView 的 Activity 中显示该部分.启动它的相关java代码很简单
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setAllowFileAccessFromFileURLs(true);
webSettings.setAllowUniversalAccessFromFileURLs(true);
mWebView.loadUrl("file:///android_asset/AndroidWebView.html");
和
AndroidWebView.html
的相关部分类似于 Transcript's demo for iOS <script type="module">
import * as my_app from "./target/my_app.js"; window.my_app = my_app;
</script>
该应用程序在模拟器上运行良好,但在真实设备上 WebView 拒绝加载 javascript 并吐出以下错误:
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.
如果我通过将 HTML 更改为强制 MIME 类型
<script type="text/javascript">
import * as my_app from "./target/my_app.js"; window.my_app = my_app;
</script>
这似乎适用于我页面的其他纯 javascript 部分(不是模块),它显然失败了
Uncaught SyntaxError: Cannot use import statement outside a module
.有没有办法强制后一个 HTML 成为一个模块,或者前一个 HTML 不那么强烈地检查 MIME 类型?
看着options for WebView我看不到任何似乎相关的东西。环顾四周,这个问题似乎正是由 this bug 引起的。 .
另一方面,在我看来,问题在于 HTML
script
的语法。接受类型的标记为 "text/javascript"
或 "module"
但不能同时使用两者(我试过了,它似乎只使用了第一个),而从语义上讲,有理由同时拥有两者。是否有解决方法,甚至两者兼而有之?我知道一种可以加载 my_app.js
的技巧。 ,但该模块将无法进一步加载其他模块(my_app.js
确实如此)。因此,除非有转译器或能够自动将我的所有模块合并为一个的东西,否则这将不起作用。 FWIW,这些模块是从 Transcrypt 的 python 生成的,所以它必须是一个自动化的,而不是手动的过程。PS:我不是 HTML 或 javascript 开发人员,这是我在这个领域的第一步,所以请不要怀疑我的猜测
PPS:我理解不在计算机上做任何这些,而是启动服务器的原因。这就是我为我的开发环境所做的。但是对于 Android 应用程序中的单个 Activity,HTTP 服务器似乎是一种矫枉过正和令人头疼的问题(跟踪端口、潜在的更多故障模式、可能在浏览器或其他应用程序中可见、额外的权限、额外的资源和电池使用,以及可能更多我没有想到的麻烦)。
最佳答案
有些事情你可以尝试。
1.
通过添加 <!DOCTYPE html>
确保它是 html 5到你的 index.html
2.
而不是使用 file://... 直接从系统加载文件,您可以使用 WebViewAssetLoader 这将返回 mimetype
https://developer.android.com/reference/kotlin/androidx/webkit/WebViewAssetLoader
3.
如果这在 webViewClient 中不起作用,您可以拦截请求并手动添加 text/javascript mimetype:
val webViewAssetLoader = WebViewAssetLoader.Builder()
.addPathHandler("/assets/", WebViewAssetLoader.AssetsPathHandler(context!!))
.build()
val webViewClient = object : WebViewClient() {
override fun shouldInterceptRequest(view: WebView?, request: WebResourceRequest): WebResourceResponse? {
val interceptedWebRequest = webViewAssetLoader.shouldInterceptRequest(request.url)
interceptedWebRequest?.let {
if (request.url.toString().endsWith("js", true)) {
it.mimeType = "text/javascript"
}
}
return interceptedWebRequest
}
}
关于javascript - 在 Android 的 WebView 中放宽 MIME 类型检查?或者强制常规javascript的模块类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60588170/