拦截并覆盖来自WebView的HTTP请求

Ole*_*gas 60 android android-webview webviewclient

我的应用程序中有一个WebView,其中一些站点被打开(总是相同的,它是我自己的页面).该站点有一些JS代码,可以从远程主机加载一些图像.

我想截取对这些图像的请求(通过URL模式)并返回我自己的内容(即另一个图像),或者根据内部应用程序逻辑保持请求不变.

有可能吗?

编辑:目前的问题状态......

WebView有能力设置WebViewClient(如Axarydax所述).WebViewClient有两个有用的方法

  • shouldOverrideUrlLoading
  • onLoadResource

shouldOverrideUrlLoading能够拦截任何URL加载,如果加载是由页面交互触发的(即单击页面上的链接,WebView.loadURL("")不会触发此方法).它还可以通过返回false来取消URL加载.这种方法不可用,导致'它无法拦截页面资源的加载(和图像,我需要拦截的是这样的页面资源).

onLoadResource每次加载页面资源(和图像!thx到jessyjones)时都会触发,但是没有办法取消它.这使得这种方法也不适合我的任务.

Axa*_*dax 69

试试这个,我在个人类似wiki的应用程序中使用它:

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

  • 您可以使用WebView的loadData()方法将一些html推送到其中。用法:webView.loadData(“ <html> ... </ html>”,“ text / html”,“ utf-8”); (2认同)
  • 从API 24开始,此版本的“ shouldOverrideUrlLoading”已被弃用。为了解决这个问题,请参见以下问题:/sf/ask/2553885211/ (2认同)

dkn*_*ler 50

看起来API级别11支持您所需的内容.见WebViewClient.shouldInterceptRequest().

  • 小心!如果您拦截浏览器尝试检索图像(或可能是任何资源)然后返回"null"(意味着让WebView继续检索图像),则此资源的任何未来请求可能只会转到缓存而不会触发`shouldInterceptRequest()`.如果你想拦截每个图像请求,你需要禁用缓存或(我做了什么)调用`WebView.clearCache(true)`. (10认同)
  • 我正在尝试添加自定义Cookie和其他标头.知道如何做到这一点? (2认同)

小智 10

据我所知,shouldOverrideUrlLoading不是为图像调用而是为超链接调用...我认为合适的方法是

@Override public void onLoadResource(WebView view, String url)

对于由webview加载的每个资源(图像,样式表,脚本)都会调用此方法,但由于它是一个空白,我还没有找到更改该URL并替换它以便加载本地资源的方法...


Esc*_*ape 9

这是我用于我的应用程序的解决方案.

我有几个资产文件夹与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;
        }
Run Code Online (Sandbox Code Playgroud)