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

WebView/WebViewClient如何拦截<link>与<image>请求并加载本地文件?

WebView拦截样式表与资源请求的解决方案

WebView会发起这类资源请求,你遇到的拦截方法未触发问题,通常是WebView配置缺失、相对路径解析错误或拦截方法使用不当导致的。以下是具体解决步骤:

1. 配置WebView基础权限

WebView需要开启文件访问权限才能加载本地相关资源,添加以下配置:

WebSettings webSettings = webView.getSettings();
// 允许访问文件
webSettings.setAllowFileAccess(true);
// API 16+ 允许从文件URL加载其他文件
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
    webSettings.setAllowFileAccessFromFileURLs(true);
    webSettings.setAllowUniversalAccessFromFileURLs(true);
}

2. 正确设置HTML加载的Base URL

如果通过loadDataWithBaseURL加载HTML字符串,必须指定正确的Base URL,否则WebView无法解析相对路径的资源请求。比如你的HTML文件存放在file:///android_asset/epub/chapters/目录下,加载时:

String htmlContent = // 读取HTML文件的内容
String baseUrl = "file:///android_asset/epub/chapters/";
webView.loadDataWithBaseURL(baseUrl, htmlContent, "text/html", "UTF-8", null);

Base URL会作为相对路径的解析基准,确保../stylesheet.css这类路径能被WebView正确转化为完整URL,进而触发拦截方法。

3. 重写shouldInterceptRequest拦截资源请求

shouldInterceptRequest是拦截资源请求的核心方法,需针对不同API版本实现重载,解析请求URL并替换为本地资源:

webView.setWebViewClient(new WebViewClient() {
    @Override
    public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Uri requestUri = request.getUrl();
            String path = requestUri.getPath();
            
            // 拦截样式表请求
            if (path.endsWith(".css")) {
                // 替换为本地样式文件的输入流,示例从assets读取
                try {
                    InputStream inputStream = getAssets().open("epub/stylesheet.css");
                    return new WebResourceResponse("text/css", "UTF-8", inputStream);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            // 拦截图片请求(包括SVG内的image)
            else if (path.endsWith(".jpeg") || path.endsWith(".jpg")) {
                try {
                    InputStream inputStream = getAssets().open("epub/image.jpeg");
                    return new WebResourceResponse("image/jpeg", null, inputStream);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return super.shouldInterceptRequest(view, request);
    }

    // 兼容低版本API(<21)
    @Override
    public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
        Uri requestUri = Uri.parse(url);
        String path = requestUri.getPath();
        
        if (path.endsWith(".css")) {
            try {
                InputStream inputStream = getAssets().open("epub/stylesheet.css");
                return new WebResourceResponse("text/css", "UTF-8", inputStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else if (path.endsWith(".jpeg") || path.endsWith(".jpg")) {
            try {
                InputStream inputStream = getAssets().open("epub/image.jpeg");
                return new WebResourceResponse("image/jpeg", null, inputStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return super.shouldInterceptRequest(view, url);
    }
});

关键注意点

  • SVG内的<image>标签使用xlink:href时,WebView会正常解析并发起请求,只要Base URL配置正确,就能被shouldInterceptRequest捕获。
  • 若资源存放在外部存储而非assets,需确保App有读取外部存储的权限,且路径处理正确(可通过FileProvider适配Android 7.0+的文件访问限制)。
  • 避免使用onLoadResource拦截,该方法仅告知资源已开始加载,无法替换资源内容;shouldOverrideUrlLoading仅拦截页面跳转类的URL,不拦截资源请求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 10:10:31