3

I'm writing an Android application which host a webview to load a webpage. I got a lot of errors like below in 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.

Please note that Javascript is executed well if it's not an inline script. For example, with an HTML file like below:

<htnl>
<head>
<script type="text/javascript" src="abc.js"></script>
</head>
<body>
<script type="text/javascript">
    alert("This is inline script");
</script>
</body>
</html>

Script in abc.js is executed properly, but the inline script is refused to execute.

I understand that the webview refuses to execute inline Javascript due to "Contect Security Policy". But the webpage need to execute those inline scripts to function properly and I cannot make any change on the webpage.

This problem only KitKat (Android 4.4)

Is there any way to overcome this problem, modify "Content Security Policy" to allow inline script to be executed.

Dong Nguyen
  • 31
  • 1
  • 5
  • possible duplicate of [Android: can't get javascript to work on WebView even with setJavaScriptEnabled(true)](http://stackoverflow.com/questions/5110916/android-cant-get-javascript-to-work-on-webview-even-with-setjavascriptenabled) – Dalorzo May 25 '14 at 16:08
  • 1
    @Dalorzo: Thanks for you reference, I saw that question already, but my problem is different. My problem related to Content-Security Policy, Javascript was executed well if it's not an inline Javascript. – Dong Nguyen May 25 '14 at 16:49
  • hey, have you found a solution to this problem? i'm facing the same thing. – EladB Jan 06 '16 at 14:08

1 Answers1

1

According to information from WebView developers, injected javascripts run in the host page itself, not in an isolated world as it is with Chromium extensions. This is why they should pass common security checkups imposed by Content Security Policy header (if it exists). As a result, it can be impossible to inject a script as a file via src attribute or inline, or in both ways, depending from the header directive (for example, if unsafe-inline is mentioned, you'll be unable to inject a script tag with inline code).

The workaround is to use loadUrl or evaluateJavascript methods to execute javascript code "as is", without adding a script tag. For example:

webview.loadUrl("javascript:alert('hello')");

will be executed successfully.

For Android 4.4 and up it's recommended to use the new evaluateJavascript method, because loadUrl has a side effect when your app is targeted to one of these newer Android versions (and I think this is the case for most projects nowadays): if the script returns a value - it will replace DOM content of the current page. On targets prior 4.4, both methods are the same except for the possibility to return a value via optional callback in evaluateJavascript.

One could think of other tricks but this should be enough to solve your problems.

Stan
  • 8,683
  • 9
  • 58
  • 102
  • Are you also saying that if I have a local hosted html file that has externally linked .js scripts in the header (i.e: ), they will not be accessible? – Mike6679 Mar 15 '21 at 14:51