简体   繁体   English

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

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

I have an app that uses WebViews.我有一个使用 WebViews 的应用程序。 I've changed my targetAPI from 18 to 19 and I'm currently testing on the new 4.4.我已将我的 targetAPI 从 18 更改为 19,并且我目前正在测试新的 4.4。 For some reason I'm getting this error: Not allowed to load local resource: file:///android_asset/webkit/android-weberror.png on 4.4 but not on 4.3, does somebody have clue why?出于某种原因,我收到此错误: Not allowed to load local resource: file:///android_asset/webkit/android-weberror.png在 4.4 但不是在 4.3,有人知道为什么吗?

Since I don't really know where to start looking I can't give the complete code.由于我真的不知道从哪里开始寻找我无法提供完整的代码。 It might have something to do with the shouldInterceptRequest(Webview, String) method in the WebViewClient but I'm not really sure.它可能与 WebViewClient 中的shouldInterceptRequest(Webview, String)方法有关,但我不太确定。 If I know more, I'll update the question.如果我知道更多,我会更新问题。

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. 有点干扰,但我通过引入“唯一令牌”并使用shouldInterceptRequest覆盖实现WebViewClient来解决这个问题。

First, change the URL from file:///android/asset to a relative path with a uniquely identifying token: 首先,将URL从file:///android/asset更改为具有唯一标识标记的相对路径:

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

Then, override shouldInterceptRequest as follows: 然后,覆盖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;
    }
});

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

I found that I had this problem on KitKat when I used webview.loadData() . 当我使用webview.loadData()时,我发现我在KitKat上遇到了这个问题。 If I instead used webview.loadDataWithBaseURL() (I used "file:///android_asset/" as the baseURL), then the problem went away. 如果我改为使用webview.loadDataWithBaseURL() (我使用“file:/// android_asset /”作为baseURL),那么问题就消失了。

The methods setAllowFileAccess() , setAllowFileAccessFromFileURLs() , and setAllowUniversalAccessFromFileURLs() did not have any affect that I could see. 方法setAllowFileAccess()setAllowFileAccessFromFileURLs()setAllowUniversalAccessFromFileURLs()没有任何影响,我可以看到。

"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. KitKat WebView具有更强的安全限制,看起来似乎正在进行.FWIW我尝试只加载一个文件:/// android_asset URL并且它工作正常。

Did you call any of the file-related WebSettings APIs (like setAllowFileAccess(false)) by any chance? 您是否有机会调用任何与文件相关的WebSettings API(如setAllowFileAccess(false))? Are you trying to load the resource from an https: URL? 您是否尝试从https:URL加载资源?

HERE IS THE SOLUTION: This problem occurs when you try to load a file from library projects. 这是解决方案:当您尝试从库项目加载文件时,会发生此问题。 If your app depends on a library where webview and html files reside, then you need include assets from that library project into main application project while compiling. 如果您的应用程序依赖于webview和html文件所在的库,那么您需要在编译时将该库项目中的资源包含到主应用程序项目中。 For example, IntelliJ has an option to do this. 例如,IntelliJ有一个选项来执行此操作。 In the compiler settings "Include assets from dependencies into APK", but make sure that your asset files should have different names than main application has. 在编译器设置“将资源从依赖项包含到APK”中,但请确保您的资产文件应具有与主应用程序不同的名称。 You don't want library project's index.html to be overridden by main app. 您不希望主应用程序覆盖库项目的index.html。

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. 从API级别19开始强制执行此权限。

The solution below works for me. 以下解决方案适合我。

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

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

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: 以下是doc对setMixedContentMode的说法:

Configures the WebView's behavior when a secure origin attempts to load a resource from an insecure origin. 当安全源尝试从不安全的源加载资源时,配置WebView的行为。 By default, apps that target KITKAT or below default to MIXED_CONTENT_ALWAYS_ALLOW. 默认情况下,以KITKAT或以下为目标的应用默认为MIXED_CONTENT_ALWAYS_ALLOW。 Apps targeting LOLLIPOP default to MIXED_CONTENT_NEVER_ALLOW. 针对LOLLIPOP的应用默认为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. WebView的首选和最安全的操作模式是MIXED_CONTENT_NEVER_ALLOW,强烈建议不要使用MIXED_CONTENT_ALWAYS_ALLOW。

However, this might not answer the original question; 但是,这可能无法回答原来的问题; it looks like the restriction only started with Lollipop. 看起来这个限制只是从Lollipop开始的。

I've found a nice workaround in this link : http://trentmilton.com/android-webview.html 我在这个链接中找到了一个很好的解决方法: http//trentmilton.com/android-webview.html

A summary of the solution is something like: 解决方案的摘要如下:

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

Hope that helps 希望有所帮助

The proper way to handle this is by using WebViewAssetLoader from AndroidX (the successor to the Android Support Library).处理此问题的正确方法是使用AndroidX中的WebViewAssetLoader (Android 支持库的后续版本)。 This class makes it possible for any page element to make use of asset files.这个 class 使任何页面元素都可以使用资产文件。

You can add the library to your project by adding this line to your app's build.gradle :您可以通过将此行添加到应用程序的build.gradle来将库添加到您的项目中:

implementation 'androidx.webkit:webkit:1.5.0'

Create an instance of WebViewAssetLoader and point it to the asset path you wish to expose to the WebView:创建WebViewAssetLoader的实例并将其指向您希望向 WebView 公开的资产路径:

val assetLoader = WebViewAssetLoader.Builder()
    .addPathHandler("/some/path/", AssetsPathHandler(context))
    .build()

Then override WebViewClient.shouldInterceptRequest() :然后覆盖WebViewClient.shouldInterceptRequest()

webView.webViewClient = object : WebViewClient() {
    override fun shouldInterceptRequest(
        view: WebView,
        request: WebResourceRequest
    ): WebResourceResponse? {
        return assetLoader.shouldInterceptRequest(request.url)
    }
}

Now, instead of file:///android_asset/... , your URLs become:现在,您的 URL 不再是file:///android_asset/... ,而是:

https://appassets.androidplatform.net/...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 “不允许加载本地资源:file:///android_asset/webkit/android-weberror.png”) - “Not allowed to load local resource: file:///android_asset/webkit/android-weberror.png”) 来自file:///android_asset/webkit/android-weberror.png的不安全内容 - insecure content from file:///android_asset/webkit/android-weberror.png android不允许加载本地资源:file:/// android_asset - android Not allowed to load local resource:file:///android_asset 不允许加载本地资源:file:/// android_asset phonegap - Not allowed to load local resource:file:///android_asset phonegap Xamarin Android Webview:不允许加载本地资源“file:///android_asset/*.css”来源:(1)? - Xamarin Android Webview: Not allowed to load local resource “file:///android_asset/*.css” source: (1)? android上的phonegap说:不允许加载本地资源:file:///android_asset/www/app/fb.js - phonegap on android says: Not allowed to load local resource: file:///android_asset/www/app/fb.js 不允许加载本地资源:file:///android_asset/... with Crosswalk 16+ - Not allowed to load local resource: file:///android_asset/... with Crosswalk 16+ Xamarin-文件:/// android_asset - Xamarin - file:///android_asset 路径“file:/// android_asset /”记录在哪里? - Where is the path “file:///android_asset/” documented? file:/// android_asset不起作用 - file:///android_asset does not work
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM