Kitkat kills: Not allowed to load local resource: file:///android_asset/webkit/android-weberror.png

后端 未结 8 1019
半阙折子戏
半阙折子戏 2020-11-30 03:54

I have an app that uses WebViews. I\'ve changed my targetAPI from 18 to 19 and I\'m currently testing on the new 4.4. For some reason I\'m getting this error: Not allo

相关标签:
8条回答
  • 2020-11-30 04:31

    The solution below works for me.

    webview.loadDataWithBaseURL( baseUrl, htmlStr, "text/html", "UTF-8", "");
    

    where baseUrl is your external domain, not file:///android_asset/ (i.e. http://a.domain.com ).

    0 讨论(0)
  • 2020-11-30 04:32

    "Not allowed to load local resource" is a security origin error. The KitKat WebView has stronger security restrictions and it seems like these are kicking in. FWIW I tried just loading a file:///android_asset URL and it worked fine.

    Did you call any of the file-related WebSettings APIs (like setAllowFileAccess(false)) by any chance? Are you trying to load the resource from an https: URL?

    0 讨论(0)
  • 2020-11-30 04:36

    A bit of an intrusive hack, but I worked around this issue by introducing a "unique token" and implementing the WebViewClient with a shouldInterceptRequest override.

    First, change the URL from file:///android/asset to a relative path with a uniquely identifying token:

    <script src="**injection**www/scripts.js"></script>
    

    Then, override shouldInterceptRequest as follows:

    // Injection token as specified in HTML source
    private static final String INJECTION_TOKEN = "**injection**";
    
    webView.setWebViewClient(new WebViewClient() {
    
        @Override
        public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
            WebResourceResponse response = super.shouldInterceptRequest(view, url);
            if(url != null && url.contains(INJECTION_TOKEN)) {
                String assetPath = url.substring(url.indexOf(INJECTION_TOKEN) + INJECTION_TOKEN.length(), url.length());
                try {
                    response = new WebResourceResponse(
                            "application/javascript",
                            "UTF8",
                            getContext().getAssets().open(assetPath)
                    );
                } catch (IOException e) {
                    e.printStackTrace(); // Failed to load asset file
                }
            }
            return response;
        }
    });
    

    This is likely to degrade WebView performance slightly as we are calling the contains() on each resource which is attempted to be loaded, but it's the only workaround I've found to this issue.

    0 讨论(0)
  • 2020-11-30 04:37

    I found that I had this problem on KitKat when I used webview.loadData(). If I instead used webview.loadDataWithBaseURL() (I used "file:///android_asset/" as the baseURL), then the problem went away.

    The methods setAllowFileAccess(), setAllowFileAccessFromFileURLs(), and setAllowUniversalAccessFromFileURLs() did not have any affect that I could see.

    0 讨论(0)
  • 2020-11-30 04:41

    It may be needed to add a permission

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    to a manifest.

    This permission is enforced starting in API level 19.

    0 讨论(0)
  • 2020-11-30 04:44

    Not available at the time, this now works (though it's not recommended):

    webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
    

    Here's what the doc says about setMixedContentMode:

    Configures the WebView's behavior when a secure origin attempts to load a resource from an insecure origin. By default, apps that target KITKAT or below default to MIXED_CONTENT_ALWAYS_ALLOW. Apps targeting LOLLIPOP default to MIXED_CONTENT_NEVER_ALLOW. The preferred and most secure mode of operation for the WebView is MIXED_CONTENT_NEVER_ALLOW and use of MIXED_CONTENT_ALWAYS_ALLOW is strongly discouraged.

    However, this might not answer the original question; it looks like the restriction only started with Lollipop.

    0 讨论(0)
提交回复
热议问题