webentwicklung-frage-antwort-db.com.de

Kitkat tötet: Lokale Ressourcen dürfen nicht geladen werden: Datei: ///Android_asset/webkit/Android-weberror.png

Ich habe eine App, die WebViews verwendet. Ich habe meine targetAPI von 18 auf 19 geändert und teste gerade den neuen 4.4. Aus irgendeinem Grund erhalte ich diese Fehlermeldung: Not allowed to load local resource: file:///Android_asset/webkit/Android-weberror.png auf 4.4, aber nicht auf 4.3. Hat jemand eine Ahnung, warum?

Da ich nicht wirklich weiß, wo ich anfangen soll, kann ich nicht den vollständigen Code angeben. Es hat etwas mit der shouldInterceptRequest(Webview, String)-Methode im WebViewClient zu tun, aber ich bin mir nicht wirklich sicher. Wenn ich mehr weiß, werde ich die Frage aktualisieren.

21
dumazy

"Lokale Ressource darf nicht geladen werden" ist ein Sicherheitsfehler. Das KitKat WebView hat strengere Sicherheitsbeschränkungen, und es scheint, als würden diese einspringen. FWIW Ich habe versucht, einfach eine Datei zu laden: /// Android_asset-URL, und es hat gut funktioniert.

Haben Sie zufällig eine der dateibezogenen WebSettings-APIs (wie setAllowFileAccess (false)) aufgerufen? Versuchen Sie, die Ressource von einer https: URL zu laden?

8
marcin.kosiba

Ein etwas aufdringlicher Hack, aber ich habe dieses Problem umgangen, indem ich ein "einzigartiges Token" eingeführt und die WebViewClient mit einer shouldInterceptRequest-Überschreibung implementiert habe.

Ändern Sie zunächst die URL von file:///Android/asset in einen relativen Pfad mit einem eindeutigen Token:

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

Überschreiben Sie dann shouldInterceptRequest wie folgt:

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

Dies führt wahrscheinlich zu einer Beeinträchtigung der WebView-Leistung etwas , da wir contains() für jede Ressource aufrufen, die geladen werden soll. Dies ist jedoch die einzige Problemumgehung, die ich für dieses Problem gefunden habe.

20
CodingIntrigue

Ich habe festgestellt, dass ich dieses Problem bei KitKat hatte, als ich webview.loadData() verwendete. Wenn ich stattdessen webview.loadDataWithBaseURL() verwendet habe (ich habe "file: /// Android_asset /" als baseURL verwendet), ist das Problem behoben.

Die Methoden setAllowFileAccess(), setAllowFileAccessFromFileURLs() und setAllowUniversalAccessFromFileURLs() hatten keine Auswirkungen, die ich sehen konnte.

17
mikejonesguy

HIER IS DIE LÖSUNG: Dieses Problem tritt auf, wenn Sie versuchen, eine Datei aus Bibliotheksprojekten zu laden. Wenn Ihre App von einer Bibliothek abhängig ist, in der sich Webview- und HTML-Dateien befinden, müssen Sie beim Kompilieren Elemente aus diesem Bibliotheksprojekt in das Hauptanwendungsprojekt einschließen. IntelliJ hat beispielsweise eine Option, dies zu tun. Stellen Sie in den Compiler-Einstellungen "Assets aus Abhängigkeiten in APK einschließen" ein. Stellen Sie jedoch sicher, dass Ihre Asset-Dateien einen anderen Namen haben als die Hauptanwendung. Sie möchten nicht, dass die index.html des Bibliotheksprojekts von der Hauptanwendung überschrieben wird.

5
Nizzy

Die Lösung unten funktioniert für mich.

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

dabei ist baseUrl Ihre externe Domain und nicht file: /// Android_asset/(d. h. http://a.domain.com ).

1
CodeRen

Es kann erforderlich sein, eine Berechtigung hinzuzufügen 

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

zu einem Manifest.

Diese Berechtigung wird ab API-Ebene 19 erzwungen.

1
nor_miya

Zur Zeit nicht verfügbar, dies funktioniert jetzt (obwohl es nicht empfohlen wird):

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

Das sagt das Dokument über setMixedContentMode:

Konfiguriert das Verhalten der WebView, wenn ein sicherer Origin versucht, eine Ressource aus einem unsicheren Origin zu laden. Standardmäßig setzen Apps, die auf KitKat oder darunter abzielen, auf MIXED_CONTENT_ALWAYS_ALLOW. Apps, die auf Lollipop abzielen, verwenden standardmäßig MIXED_CONTENT_NEVER_ALLOW. Der bevorzugte und sicherste Betriebsmodus für das WebView ist MIXED_CONTENT_NEVER_ALLOW. Die Verwendung von MIXED_CONTENT_ALWAYS_ALLOW wird dringend empfohlen.

Dies kann jedoch die ursprüngliche Frage nicht beantworten. Es sieht so aus, als ob die Einschränkung nur mit Lollipop begann.

1
wamfous

Ich habe in diesem Link eine Problemumgehung in Nizza gefunden: http://trentmilton.com/Android-webview.html

Eine Zusammenfassung der Lösung sieht so aus: 

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

Hoffentlich hilft das

0
akdeveloper