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

Android WebView自定义缓存拦截请求后页面渲染异常求助

解决WebView拦截请求后页面渲染异常的问题

你的代码存在几个关键问题,直接导致了页面渲染异常,以下是具体分析和修复方案:

问题核心原因

  • 未传递原WebView的请求头:服务器会根据User-Agent、Accept等请求头返回适配内容,直接用HttpURLConnection发起请求缺少这些头,会导致返回非移动端页面或不兼容资源
  • 未处理响应头传递:WebView需要依赖完整的响应头(如缓存、样式相关字段)来正确渲染页面
  • 未正确解析MIME类型与编码:原代码对contentType的处理过于简单,可能导致WebView无法识别资源类型
  • 未处理重定向:Google页面存在重定向逻辑,默认HttpURLConnection的处理不符合WebView预期

修复后的代码

@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
    HttpURLConnection conn = null;
    try {
        URL url = new URL(request.getUrl().toString());
        conn = (HttpURLConnection) url.openConnection();
        
        // 复制原WebView的所有请求头,保证请求与WebView默认行为一致
        for (Map.Entry<String, String> header : request.getRequestHeaders().entrySet()) {
            conn.setRequestProperty(header.getKey(), header.getValue());
        }
        
        // 开启自动重定向,匹配WebView默认逻辑
        conn.setInstanceFollowRedirects(true);
        
        String contentType = conn.getContentType();
        String mimeType = null;
        String encoding = null;
        
        // 正确解析Content-Type中的MIME类型和编码
        if (contentType != null) {
            String[] parts = contentType.split(";");
            mimeType = parts[0].trim();
            for (String part : parts) {
                String trimmedPart = part.trim();
                if (trimmedPart.startsWith("charset=")) {
                    encoding = trimmedPart.substring("charset=".length());
                    break;
                }
            }
        }
        
        // 若MIME类型为空,从URL后缀推断
        if (mimeType == null) {
            String fileExt = MimeTypeMap.getFileExtensionFromUrl(url.toString());
            mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExt);
        }
        
        return new WebResourceResponse(
                mimeType,
                encoding != null ? encoding : conn.getContentEncoding(),
                conn.getResponseCode(),
                conn.getResponseMessage(),
                conn.getHeaderFields(), // 传递完整响应头
                conn.getInputStream()
        );
    } catch (Exception e) {
        e.printStackTrace();
        return super.shouldInterceptRequest(view, request); // 异常时交还给WebView默认处理
    } finally {
        if (conn != null) {
            conn.disconnect(); // 确保连接关闭
        }
    }
}

额外注意事项

  • 不要盲目拦截所有请求,可先判断资源是否在自定义缓存中,再决定是否拦截
  • 处理HTTPS请求时,需确保HttpURLConnection能正确处理SSL证书,避免证书验证失败导致资源加载失败
  • 可通过Log打印请求头、响应头信息,排查服务器返回内容是否符合预期

页面渲染异常效果:
Google页面渲染异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 14:43:28