Kitkat 杀死:不允许加载本地资源:file:///android_asset/webkit/android-weberror.png

Posted

技术标签:

【中文标题】Kitkat 杀死:不允许加载本地资源:file:///android_asset/webkit/android-weberror.png【英文标题】:Kitkat kills: Not allowed to load local resource: file:///android_asset/webkit/android-weberror.png 【发布时间】:2013-11-15 09:01:27 【问题描述】:

我有一个使用 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) 方法有关,但我不太确定。如果我知道更多,我会更新问题。

【问题讨论】:

如何加载初始页面?是来自服务器还是 APK 中的 html 文件? 你好@dumazy!你找到解决办法了吗? @rahulritesh 不是真的,它与 shouldInterceptRequest 有关,但我没有找到正确的解决方案,所以我决定采取另一种方法...... 你能告诉我你做了什么吗?我无法使用 Android 4.4 在我的应用中加载我的缓存数据 我忘记打开 WiFi 时遇到了同样的问题,因此您可能只需要确保您有互联网连接。 【参考方案1】:

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

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

【讨论】:

在the docs 中的allow... 方法的底部有一条注释说: > 请注意,此设置仅影响javascript 对文件方案资源的访问。对此类资源的其他访问(例如,从图像 HTML 元素)不受影响。问题是如何影响 HTML 元素!? 谢谢! loadDataWithBaseURL() 还帮助我通过自定义内容提供程序(“content://myapp.something.localfiles/.../video.mp4”)播放本地视频,它仅使用 loadData() 就停止了在 KitKat 上的工作 太棒了!它就像一个魅力。当我愿意将一些静态 js/css 文件加载到我的 webview 中时,我遇到了这个问题,使用这种方式解决了。谢谢!【参考方案2】:

有点侵入性,但我通过引入“唯一令牌”并使用 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 上显示图像。在 KitKat 之前,它一直可以正常工作,所以我不得不做一些类似的事情来拦截请求,并使用图像的输入流创建响应。 有没有办法将代码应用到 ios > Objective C ? 在抛出“不允许加载本地资源”之前,shouldInterceptRequest 甚至不会在尝试从“file://”加载时被调用。 @Michael 没错。这个答案明确地替换 file:/// URL 为一个相对 URL,带有一个标记,以便调用该方法。【参考方案3】:

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

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

【讨论】:

如何在 kitkat 中从 sdcard 加载本地 html 文件? @marcin.kosiba https 的解决方案是什么?谢谢。 @AdamSilver - 使用 shouldInterceptRequest 在 https:// URL 上托管您的本地资源。 原来 setAllowFileAccess 默认是禁用的,设置为 true 对我有用【参考方案4】:

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

【讨论】:

【参考方案5】:

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

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

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

【讨论】:

谢谢这种方法对我有用(Android 5.1.1)【参考方案6】:

可能需要添加权限

&lt;uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /&gt;

到清单。

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

【讨论】:

这解决了我的问题 - 与 OP 不同,我试图从 sdcard 加载一个 html 文件并收到错误“不允许加载本地资源:file:///android_asset/webkit/android- weberror.png""【参考方案7】:

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

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。

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

【讨论】:

【参考方案8】:

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

解决方案的摘要类似于:

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

希望有帮助

【讨论】:

以上是关于Kitkat 杀死:不允许加载本地资源:file:///android_asset/webkit/android-weberror.png的主要内容,如果未能解决你的问题,请参考以下文章

Xamarin 不允许加载本地资源文件

“不允许加载本地资源:file:///C:..jpg” Java EE Tomcat

Cordova 10 和 Android SDK 30:无法访问本地文件(“不允许加载本地资源:file:///storage/emulated/0/Android/data...”)

不允许加载本地资源:ionic 3 android

Electron Builder:不允许加载本地资源:app.asar/build/index.html

jQuery window.open() 不允许在 Chrome 中加载本地资源