[英]“Not allowed to load local resource: file:///android_asset/webkit/android-weberror.png”)
[英]Kitkat kills: Not allowed to load local resource: file:///android_asset/webkit/android-weberror.png
我有一個使用 WebViews 的應用程序。 我已將我的 targetAPI 從 18 更改為 19,並且我目前正在測試新的 4.4。 出於某種原因,我收到此錯誤: Not allowed to load local resource: file:///android_asset/webkit/android-weberror.png
在 4.4 但不是在 4.3,有人知道為什么嗎?
由於我真的不知道從哪里開始尋找我無法提供完整的代碼。 它可能與 WebViewClient 中的shouldInterceptRequest(Webview, String)
方法有關,但我不太確定。 如果我知道更多,我會更新問題。
有點干擾,但我通過引入“唯一令牌”並使用shouldInterceptRequest
覆蓋實現WebViewClient
來解決這個問題。
首先,將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()
,但這是我發現此問題的唯一解決方法。
當我使用webview.loadData()
時,我發現我在KitKat上遇到了這個問題。 如果我改為使用webview.loadDataWithBaseURL()
(我使用“file:/// android_asset /”作為baseURL),那么問題就消失了。
方法setAllowFileAccess()
, setAllowFileAccessFromFileURLs()
和setAllowUniversalAccessFromFileURLs()
沒有任何影響,我可以看到。
“不允許加載本地資源”是安全起源錯誤。 KitKat WebView具有更強的安全限制,看起來似乎正在進行.FWIW我嘗試只加載一個文件:/// android_asset URL並且它工作正常。
您是否有機會調用任何與文件相關的WebSettings API(如setAllowFileAccess(false))? 您是否嘗試從https:URL加載資源?
這是解決方案:當您嘗試從庫項目加載文件時,會發生此問題。 如果您的應用程序依賴於webview和html文件所在的庫,那么您需要在編譯時將該庫項目中的資源包含到主應用程序項目中。 例如,IntelliJ有一個選項來執行此操作。 在編譯器設置“將資源從依賴項包含到APK”中,但請確保您的資產文件應具有與主應用程序不同的名稱。 您不希望主應用程序覆蓋庫項目的index.html。
可能需要添加權限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
到清單。
從API級別19開始強制執行此權限。
以下解決方案適合我。
webview.loadDataWithBaseURL( baseUrl, htmlStr, "text/html", "UTF-8", "");
其中baseUrl
是您的外部域,而不是file:/// android_asset /(即http://a.domain.com )。
當時不可用,現在可以使用(雖然不推薦):
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開始的。
我在這個鏈接中找到了一個很好的解決方法: http : //trentmilton.com/android-webview.html
解決方案的摘要如下:
WebView webView = new WebView(this); // this is the context
webView.getSettings().setDomStorageEnabled(true);
希望有所幫助
處理此問題的正確方法是使用AndroidX中的WebViewAssetLoader (Android 支持庫的后續版本)。 這個 class 使任何頁面元素都可以使用資產文件。
您可以通過將此行添加到應用程序的build.gradle
來將庫添加到您的項目中:
implementation 'androidx.webkit:webkit:1.5.0'
創建WebViewAssetLoader
的實例並將其指向您希望向 WebView 公開的資產路徑:
val assetLoader = WebViewAssetLoader.Builder()
.addPathHandler("/some/path/", AssetsPathHandler(context))
.build()
然后覆蓋WebViewClient.shouldInterceptRequest()
:
webView.webViewClient = object : WebViewClient() {
override fun shouldInterceptRequest(
view: WebView,
request: WebResourceRequest
): WebResourceResponse? {
return assetLoader.shouldInterceptRequest(request.url)
}
}
現在,您的 URL 不再是file:///android_asset/...
,而是:
https://appassets.androidplatform.net/...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.