我正在编写一个 Android 应用程序,它托管一个 webview 来加载一个网页。我在 logcat 中遇到了很多如下错误:
Refused to execute inline script because it violates the following Content Security Policy directive: "default-src 'self'". Note that 'script-src' was not explicitly set, so 'default-src' is used as a fallback.
请注意,如果不是内联脚本,Javascript 可以很好地执行。 例如,使用如下 HTML 文件:
<htnl>
<head>
<script type="text/javascript" src="abc.js"></script>
</head>
<body>
<script type="text/javascript">
alert("This is inline script");
</script>
</body>
</html>
abc.js中的脚本可以正常执行,但是内联脚本拒绝执行。
我知道 webview 由于“Contect Security Policy”而拒绝执行内联 Javascript。但是网页需要执行那些内联脚本才能正常运行,我无法在网页上进行任何更改。
此问题仅适用于 KitKat (Android 4.4)
有没有办法克服这个问题,修改“内容安全策略”以允许执行内联脚本。
最佳答案
根据 WebView 开发人员的信息,注入(inject)的 javascript 在主机页面本身运行,而不是像 Chromium 扩展那样在孤立的世界中运行。这就是为什么他们应该通过内容安全策略 header (如果存在)强加的常见安全检查。因此,可能无法通过 src
属性或内联或两种方式将脚本作为文件注入(inject),具体取决于 header 指令(例如,如果 unsafe-inline
被提及,你将无法注入(inject)带有内联代码的脚本标签。
解决方法是使用 loadUrl
或 evaluateJavascript
方法“按原样”执行 javascript 代码,而不添加脚本标记。例如:
webview.loadUrl("javascript:alert('hello')");
将执行成功。
对于 Android 4.4 及更高版本,建议使用新的 evaluateJavascript
方法,因为当您的应用针对这些较新的 Android 版本之一时,loadUrl
会产生副作用(我认为现在大多数项目都是这种情况):如果脚本返回一个值 - 它将替换当前页面的 DOM 内容。在 4.4 之前的目标上,这两种方法是相同的,除了可以通过 evaluateJavascript
中的可选回调返回一个值。
人们可以想出其他技巧,但这应该足以解决您的问题。
关于javascript - Android webview 拒绝执行内联脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23857273/