27

我有一个使用 WebViews 的应用程序。我已将我的 targetAPI 从 18 更改为 19,并且我目前正在测试新的 4.4。出于某种原因,我收到了这个错误:Not allowed to load local resource: file:///android_asset/webkit/android-weberror.png在 4.4 但不是在 4.3,有人知道为什么吗?

由于我真的不知道从哪里开始寻找我无法提供完整的代码。它可能与shouldInterceptRequest(Webview, String)WebViewClient 中的方法有关,但我不太确定。如果我知道更多,我会更新问题。

4

8 回答 8

25

我发现我在使用 KitKat 时遇到了这个问题webview.loadData()。如果我改为使用webview.loadDataWithBaseURL()(我使用“file:///android_asset/”作为 baseURL),那么问题就消失了。

方法setAllowFileAccess(),setAllowFileAccessFromFileURLs()setAllowUniversalAccessFromFileURLs()没有我能看到的任何影响。

于 2014-01-07T22:28:52.070 回答
22

有点侵入性的黑客攻击,但我通过引入“唯一令牌”并WebViewClient使用shouldInterceptRequest覆盖来解决这个问题。

首先,将 URL 从 更改为file:///android/asset具有唯一标识令牌的相对路径:

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

然后,覆盖shouldInterceptRequest如下:

// 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;
    }
});

这可能会稍微降低 WebView 的性能,因为我们在contains()尝试加载的每个资源上调用 ,但这是我发现的唯一解决此问题的方法。

于 2014-01-08T09:59:02.033 回答
9

“不允许加载本地资源”是安全源错误。KitKat WebView 具有更强的安全限制,似乎这些限制正在发挥作用。FWIW 我尝试只加载一个 file:///android_asset URL,它工作正常。

您是否调用了任何与文件相关的 WebSettings API(如 setAllowFileAccess(false))?您是否尝试从 https: URL 加载资源?

于 2013-11-15T14:31:10.313 回答
5

这是解决方案:当您尝试从库项目加载文件时会出现此问题。如果您的应用程序依赖于 webview 和 html 文件所在的库,那么您需要在编译时将该库项目中的资产包含到主应用程序项目中。例如,IntelliJ 可以选择执行此操作。在编译器设置中“将依赖项中的资产包含到 APK 中”,但请确保您的资产文件的名称应与主应用程序的名称不同。您不希望库项目的 index.html 被主应用程序覆盖。

于 2014-01-18T01:24:22.667 回答
2

下面的解决方案对我有用。

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

您的外部域在哪里baseUrl,而不是 file:///android_asset/ (即http://a.domain.com)。

于 2014-10-10T06:32:24.743 回答
1

可能需要添加权限

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

到清单。

从 API 级别 19 开始强制执行此权限。

于 2014-09-24T07:10:39.617 回答
1

当时不可用,现在可以使用(尽管不推荐):

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

以下是文档关于 setMixedContentMode 的说明:

当安全源尝试从不安全的源加载资源时,配置 WebView 的行为。默认情况下,面向 KITKAT 或更低版本的应用默认为 MIXED_CONTENT_ALWAYS_ALLOW。以 LOLLIPOP 为目标的应用默认为 MIXED_CONTENT_NEVER_ALLOW。WebView 的首选和最安全的操作模式是 MIXED_CONTENT_NEVER_ALLOW,强烈建议不要使用 MIXED_CONTENT_ALWAYS_ALLOW。

但是,这可能无法回答最初的问题;看起来限制只是从棒棒糖开始的。

于 2016-05-27T14:18:30.520 回答
0

我在这个链接中找到了一个很好的解决方法:http: //trentmilton.com/android-webview.html

解决方案的摘要类似于:

WebView webView = new WebView(this); // this is the context
webView.getSettings().setDomStorageEnabled(true);

希望有帮助

于 2015-03-25T16:52:22.650 回答