You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android WebView拦截base64格式图片失败,求解决方案

Android WebView拦截JS注入的Base64图片问题解决

问题背景

在Android WebView中使用WebViewClient的shouldInterceptRequest方法过滤图片,尝试用正则表达式data:image/(jpg|png|jpeg);base64,或直接判断url.contains("data:image")拦截Google的Base64格式图片(示例:data:image/jpeg;base64,+),但均未成功。后续调研得知这类图片是通过JS动态注入的背景图。

无效原因

shouldInterceptRequest仅能拦截网络请求,而data:image格式的Base64图片是直接嵌入在页面中的本地数据,不会触发WebView的网络请求流程;JS动态注入的这类图片更是在DOM渲染阶段生成,完全不走网络请求通道,因此该方法无法捕获到这类图片资源。

解决方法:通过JS注入拦截处理

我们可以通过向WebView注入自定义JS脚本,在页面DOM层面直接处理Base64图片,覆盖静态渲染和动态生成的内容场景。

1. 开启WebView的JS支持

首先确保WebView允许执行JS:

webView.getSettings().setJavaScriptEnabled(true);

2. 注入JS脚本处理静态页面

在WebViewClient的onPageFinished方法中注入脚本,页面加载完成后一次性清理Base64图片:

@Override
public void onPageFinished(WebView view, String url) {
    super.onPageFinished(view, url);
    // 注入JS清理Base64图片
    view.loadUrl("javascript:(function(){" +
        // 遍历所有元素,移除含data:image的背景图
        "var elements = document.getElementsByTagName('*');" +
        "for(var i=0; i<elements.length; i++){" +
        "   var bg = elements[i].style.backgroundImage;" +
        "   if(bg && bg.indexOf('data:image') !== -1){" +
        "       elements[i].style.backgroundImage = 'none';" +
        "   }" +
        "}" +
        // 处理img标签的Base64图片
        "var imgs = document.getElementsByTagName('img');" +
        "for(var j=0; j<imgs.length; j++){" +
        "   var src = imgs[j].src;" +
        "   if(src && src.indexOf('data:image') !== -1){" +
        "       imgs[j].src = '';" +
        "       imgs[j].style.display = 'none';" +
        "   }" +
        "}" +
    "})()");
}

3. 监听DOM变化处理动态内容

如果页面存在JS动态生成的内容(如AJAX加载、动态DOM插入),需要通过MutationObserver监听DOM变化,实时清理Base64图片:

@Override
public void onPageFinished(WebView view, String url) {
    super.onPageFinished(view, url);
    view.loadUrl("javascript:(function(){" +
        // 定义统一清理函数
        "function clearBase64Images(){" +
        "   var elements = document.getElementsByTagName('*');" +
        "   for(var i=0; i<elements.length; i++){" +
        "       var bg = elements[i].style.backgroundImage;" +
        "       // 精准匹配目标图片格式的Base64资源" +
        "       if(bg && /data:image\\/(jpg|png|jpeg|svg|ico|webp|tif|tiff|bmp|eps|apng|avif|jfif|pjpeg|pjp|cur);base64,/.test(bg)){" +
        "           elements[i].style.backgroundImage = 'none';" +
        "       }" +
        "   }" +
        "   var imgs = document.getElementsByTagName('img');" +
        "   for(var j=0; j<imgs.length; j++){" +
        "       var src = imgs[j].src;" +
        "       if(src && /data:image\\/(jpg|png|jpeg|svg|ico|webp|tif|tiff|bmp|eps|apng|avif|jfif|pjpeg|pjp|cur);base64,/.test(src)){" +
        "           imgs[j].src = '';" +
        "           imgs[j].style.display = 'none';" +
        "       }" +
        "   }" +
        "}" +
        // 页面加载完成后先执行一次清理
        "clearBase64Images();" +
        // 监听DOM变化,实时处理新生成的内容
        "var observer = new MutationObserver(function(mutations){" +
        "   mutations.forEach(function(mutation){" +
        "       // 元素样式变化或新增节点时重新清理" +
        "       if(mutation.type === 'attributes' && mutation.attributeName === 'style' || mutation.addedNodes.length > 0){" +
        "           clearBase64Images();" +
        "       }" +
        "   });" +
        "});" +
        // 监听整个body的DOM变化
        "observer.observe(document.body, {" +
        "   attributes: true," +
        "   childList: true," +
        "   subtree: true" +
        "});" +
    "})()");
}

原问题代码参考

用户原拦截代码(仅作参考,无法处理JS注入的Base64图片):

@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
    String url = request.getUrl().toString();
    if (imgCheck(url,res))
    {
        return new WebResourceResponse(
                BrowserUnit.MIME_TYPE_TEXT_PLAIN,
                BrowserUnit.URL_ENCODING,
                new ByteArrayInputStream("".getBytes())
        );
    }
    return super.shouldInterceptRequest(view, request);
}
private static boolean isImage(String url, Resources res) {
        BufferedReader imageUrlRegex = openRawFile(res, R.raw.image_regex);
        try {
            String line = imageUrlRegex.readLine();
            while (line != null) {
                Pattern pattern = Pattern.compile(line);
                if (pattern.matcher(url).find())
                    return true;
                line = imageUrlRegex.readLine();
            }
        } catch (IOException e) {
            e.printStackTrace();
            return true;
        }
        return false;
    }

使用的正则表达式:

data:image/(jpg|png|jpeg|svg|ico|webp|tif|tiff|bmp|eps|apng|avif|jfif|pjpeg|pjp|cur);base64,

内容的提问来源于stack exchange,提问作者user19627732

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 03:15:58