Киткат убивает: Не разрешено загружать локальный ресурс: file:///android_asset/webkit/android-weberror.png
У меня есть приложение, которое использует WebView. Я изменил свой targetAPI с 18 до 19, и сейчас я тестирую новый 4.4. По какой-то причине я получаю эту ошибку: Not allowed to load local resource: file:///android_asset/webkit/android-weberror.png
в 4.4, но не в 4.3, кто-нибудь подсказывает почему?
Так как я не знаю, с чего начать, я не могу дать полный код. Это может иметь какое-то отношение к методу shouldInterceptRequest(Webview, String)
в WebViewClient, но я не уверен. Если я знаю больше, я обновлю вопрос.
Ответы
Ответ 1
"Не разрешено загружать локальный ресурс" - это ошибка источника безопасности. У KitKat WebView есть более сильные ограничения безопасности, и похоже, что они пинают. FWIW Я попробовал просто загрузить файл:///URL android_asset, и он работал нормально.
Вы случайно вызвали какие-либо связанные с файлом API WebSettings (например, setAllowFileAccess (false))? Вы пытаетесь загрузить ресурс с https: URL?
Ответ 2
Немного навязчивого взлома, но я работал над этой проблемой, введя "уникальный токен" и внедряя WebViewClient
с переопределением shouldInterceptRequest
.
Сначала измените 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()
на каждом ресурсе, который пытается быть загружен, но это единственный обходной путь, который я нашел для этой проблемы.
Ответ 3
Я обнаружил, что у меня была эта проблема в KitKat, когда я использовал webview.loadData()
. Если я вместо этого использовал webview.loadDataWithBaseURL()
(я использовал "файл:///android_asset/" как baseURL), проблема исчезла.
Методы setAllowFileAccess()
, setAllowFileAccessFromFileURLs()
и setAllowUniversalAccessFromFileURLs()
не имели никакого влияния, которое я мог видеть.
Ответ 4
ЗДЕСЬ РЕШЕНИЕ: Эта проблема возникает, когда вы пытаетесь загрузить файл из проектов библиотеки. Если ваше приложение зависит от библиотеки, в которой хранятся файлы webview и html, тогда вам необходимо включить активы из этого проекта библиотеки в основной проект приложения при компиляции. Например, IntelliJ имеет возможность сделать это. В настройках компилятора "Включить активы из зависимостей в APK", но убедитесь, что ваши файлы активов должны иметь разные имена, чем основное приложение. Вы не хотите, чтобы проект библиотеки index.html был переопределен основным приложением.
Ответ 5
Может потребоваться добавить разрешение
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
к манифесту.
Это разрешение принудительно запускается с уровня API 19.
Ответ 6
Решение ниже работает для меня.
webview.loadDataWithBaseURL( baseUrl, htmlStr, "text/html", "UTF-8", "");
где baseUrl
- ваш внешний домен, а не файл:///android_asset/(т.е. http://a.domain.com).
Ответ 7
Недоступно в то время, теперь это работает (хотя это не рекомендуется):
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.
Ответ 8
Я нашел хорошее обходное решение в этой ссылке: http://trentmilton.com/android-webview.html
Резюме решения - это что-то вроде:
WebView webView = new WebView(this); // this is the context
webView.getSettings().setDomStorageEnabled(true);
Надеюсь, что поможет
Ответ 9
У меня была такая же проблема, когда я забыл включить мой WiFi, поэтому вам просто нужно убедиться, что у вас есть интернет-соединение.