我有一个使用WebViews的应用程序。我已经将目标API从18改为19,我正在测试新的4.4。出于某种原因,我收到了这个错误:4.4 Not allowed to load local resource: file:///android_asset/webkit/android-weberror.png
而不是4.3,是否有人知道为什么?
由于我真的不知道从哪里开始看,所以我无法提供完整的代码。它可能与WebViewClient中的shouldInterceptRequest(Webview, String)
方法有关,但我不太确定。如果我知道更多,我会更新问题。
答案 0 :(得分:21)
有点干扰,但我通过引入“唯一令牌”并使用WebViewClient
覆盖实现shouldInterceptRequest
来解决此问题。
首先,将网址从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;
}
});
由于我们在尝试加载的每个资源上调用contains()
,这可能会降低WebView性能稍微,但这是我发现此问题的唯一解决方法
答案 1 :(得分:19)
当我使用webview.loadData()
时,我发现我在KitKat上遇到了这个问题。如果我改为使用webview.loadDataWithBaseURL()
(我使用“file:/// android_asset /”作为baseURL),那么问题就消失了。
方法setAllowFileAccess()
,setAllowFileAccessFromFileURLs()
和setAllowUniversalAccessFromFileURLs()
没有任何影响,我可以看到。
答案 2 :(得分:8)
“不允许加载本地资源”是安全起源错误。 KitKat WebView具有更强的安全限制,看起来似乎正在开始.FWIW我尝试只加载一个文件:/// android_asset URL并且它工作正常。
您是否有机会调用任何与文件相关的WebSettings API(如setAllowFileAccess(false))?您是否尝试从https:URL加载资源?
答案 3 :(得分:5)
这是解决方案:当您尝试从库项目加载文件时,会出现此问题。如果您的应用程序依赖于webview和html文件所在的库,那么您需要在编译时将该库项目中的资源包含到主应用程序项目中。例如,IntelliJ有一个选项来执行此操作。在编译器设置“将资源从依赖项包含到APK”中,但请确保您的资产文件应具有与主应用程序不同的名称。您不希望主应用程序覆盖库项目的index.html。
答案 4 :(得分:1)
可能需要添加权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
到清单。
此权限从API级别19开始强制执行。
答案 5 :(得分:1)
以下解决方案对我有用。
webview.loadDataWithBaseURL( baseUrl, htmlStr, "text/html", "UTF-8", "");
其中baseUrl
是您的外部域,而不是file:/// android_asset /(即http://a.domain.com)。
答案 6 :(得分:1)
当时不可用,现在可以使用(虽然不推荐):
webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
以下是doc关于setMixedContentMode的说法:
当安全源尝试从不安全的来源加载资源时,配置WebView的行为。默认情况下,以KITKAT或以下为目标的应用默认为MIXED_CONTENT_ALWAYS_ALLOW。针对LOLLIPOP的应用默认为MIXED_CONTENT_NEVER_ALLOW。 WebView的首选和最安全的操作模式是MIXED_CONTENT_NEVER_ALLOW,强烈建议不要使用MIXED_CONTENT_ALWAYS_ALLOW。
然而,这可能无法回答原来的问题;看起来限制只是从Lollipop开始。
答案 7 :(得分:0)
我在此链接中找到了一个很好的解决方法:http://trentmilton.com/android-webview.html
解决方案的摘要如下:
WebView webView = new WebView(this); // this is the context
webView.getSettings().setDomStorageEnabled(true);
希望有所帮助