[android] Перехват и переопределение HTTP-запросов из WebView



Answers

Попробуйте это, я использовал его в личном вики-подобном приложении:

webView.setWebViewClient(new WebViewClient() {
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        if (url.startsWith("foo://")) {
            // magic
            return true;
        }
        return false;
    }
});
Question

У меня есть WebView в моем приложении, в котором какой-то сайт открыт (всегда то же самое, это моя собственная страница). На сайте есть код JS, который загружает некоторые изображения с удаленного хоста.

Я хочу перехватить запросы на такие изображения (по шаблону URL) и вернуть свой собственный контент (то есть другое изображение) или оставить запрос нетронутым в зависимости от внутренней логики приложения.

Можно ли это сделать?

EDIT : Текущее состояние вопроса ...

WebView имеет возможность устанавливать WebViewClient (как отметил Axarydax). WebViewClient имеет два полезных метода

  • shouldOverrideUrlLoading
  • onLoadResource

shouldOverrideUrlLoading способен перехватывать любую загрузку URL- shouldOverrideUrlLoading , если загрузка инициируется взаимодействием страницы (т.е. нажата ссылка на странице, WebView.loadURL ("") не вызывает этот метод). Он также может отменить загрузку URL, возвращая false. Этот подход не применим, потому что «он не способен перехватывать загрузку ресурсов страницы (и изображения, которые мне нужно перехватить, - это такой ресурс страницы).

onLoadResource запускается каждый раз, когда этот ресурс страницы (и образы! thx к jessyjones) загружаются, но отменить это невозможно. Это делает этот метод не подходящим для моей задачи.




Вот мое решение, которое я использую для своего приложения.

У меня есть папка с файлами css / js / img anf.

Приложение получает все имена файлов и ищет, если запрашивается файл с таким именем. Если да, он загружает его из папки с данными.

//get list of files of specific asset folder
        private ArrayList listAssetFiles(String path) {

            List myArrayList = new ArrayList();
            String [] list;
            try {
                list = getAssets().list(path);
                for(String f1 : list){
                    myArrayList.add(f1);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return (ArrayList) myArrayList;
        }

        //get mime type by url
        public String getMimeType(String url) {
            String type = null;
            String extension = MimeTypeMap.getFileExtensionFromUrl(url);
            if (extension != null) {
                if (extension.equals("js")) {
                    return "text/javascript";
                }
                else if (extension.equals("woff")) {
                    return "application/font-woff";
                }
                else if (extension.equals("woff2")) {
                    return "application/font-woff2";
                }
                else if (extension.equals("ttf")) {
                    return "application/x-font-ttf";
                }
                else if (extension.equals("eot")) {
                    return "application/vnd.ms-fontobject";
                }
                else if (extension.equals("svg")) {
                    return "image/svg+xml";
                }
                type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
            }
            return type;
        }

        //return webresourceresponse
        public WebResourceResponse loadFilesFromAssetFolder (String folder, String url) {
            List myArrayList = listAssetFiles(folder);
            for (Object str : myArrayList) {
                if (url.contains((CharSequence) str)) {
                    try {
                        Log.i(TAG2, "File:" + str);
                        Log.i(TAG2, "MIME:" + getMimeType(url));
                        return new WebResourceResponse(getMimeType(url), "UTF-8", getAssets().open(String.valueOf(folder+"/" + str)));
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            return null;
        }

        //@TargetApi(Build.VERSION_CODES.LOLLIPOP)
        @SuppressLint("NewApi")
        @Override
        public WebResourceResponse shouldInterceptRequest(final WebView view, String url) {
            //Log.i(TAG2, "SHOULD OVERRIDE INIT");
            //String url = webResourceRequest.getUrl().toString();
            String extension = MimeTypeMap.getFileExtensionFromUrl(url);
            //I have some folders for files with the same extension
            if (extension.equals("css") || extension.equals("js") || extension.equals("img")) {
                return loadFilesFromAssetFolder(extension, url);
            }
            //more possible extensions for font folder
            if (extension.equals("woff") || extension.equals("woff2") || extension.equals("ttf") || extension.equals("svg") || extension.equals("eot")) {
                return loadFilesFromAssetFolder("font", url);
            }

            return null;
        }



Конечным решением было бы внедрение простого HTTP-сервера, прослушивающего ваш «секретный» порт в loopback. Затем вы можете заменить URL-адрес сопоставленного изображения src на что-то вроде http://localhost:123/.../mypic.jpg




Links