Intercept and override HTTP requests from WebView

后端 未结 7 733
醉话见心
醉话见心 2020-11-30 17:54

I have a WebView in my application in which some site is opened (always the same, it is my own page). The site has some JS code which loads some images from the remote host.

相关标签:
7条回答
  • 2020-11-30 18:01

    You don't mention the API version, but since API 11 there's the method WebViewClient.shouldInterceptRequest

    Maybe this could help?

    0 讨论(0)
  • 2020-11-30 18:02

    Try this, I've used it in a personal wiki-like app:

    webView.setWebViewClient(new WebViewClient() {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            if (url.startsWith("foo://")) {
                // magic
                return true;
            }
            return false;
        }
    });
    
    0 讨论(0)
  • 2020-11-30 18:08

    An ultimate solution would be to embed a simple http server listening on your 'secret' port on loopback. Then you can substitute the matched image src URL with something like http://localhost:123/.../mypic.jpg

    0 讨论(0)
  • 2020-11-30 18:11

    Here is my solution I use for my app.

    I have several asset folder with css / js / img anf font files.

    The application gets all filenames and looks if a file with this name is requested. If yes, it loads it from asset folder.

    //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;
            }
    
    0 讨论(0)
  • It looks like API level 11 has support for what you need. See WebViewClient.shouldInterceptRequest().

    0 讨论(0)
  • 2020-11-30 18:19

    This may helps:

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    @Override
    public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
        String url = request.getUrl().toString();
        WebResourceResponse response = super.shouldInterceptRequest(view, request);
        // load native js
        if (url != null && url.contains(INJECTION_TOKEN/* scheme define */)) {
    
            response = new WebResourceResponse(
                    "text/javascript",
                    "utf-8",
                    loadJsInputStream(url, JsCache.getJsFilePath(path) /* InputStream */));
        }
        return response;
    }
    
    0 讨论(0)
提交回复
热议问题