如何获取WebView请求的WebResourceResponse用于分析?
Got it, let's break down how to solve this problem. The core issue here is that when you call super.shouldInterceptRequest(view, request) and get null, you can't directly access the original response the WebView would load on its own. But we have two practical workarounds depending on what part of the response you need to analyze.
Option 1: Manually Replicate the Request to Capture Full Response (Headers + Body)
If you need to inspect the entire response body (not just headers), you can manually send the same request as WebView, capture the response for analysis, then pass it back to WebView. This way, WebView loads the content normally, and you get full access to the response.
Here's a code example using OkHttp (you can also use HttpURLConnection if preferred):
@Override public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) { String requestUrl = request.getUrl().toString(); // Filter requests you want to analyze (adjust this logic to your needs) if (isTargetRequest(requestUrl)) { OkHttpClient client = new OkHttpClient.Builder() // Sync WebView's cookies to OkHttp to ensure consistent requests .cookieJar(new CookieJar() { @Override public void saveFromResponse(HttpUrl url, List<Cookie> cookies) { // Optional: Sync cookies back to WebView if needed } @Override public List<Cookie> loadForRequest(HttpUrl url) { // Get cookies from WebView String cookie = CookieManager.getInstance().getCookie(url.toString()); if (cookie == null) return Collections.emptyList(); return Cookie.parseAll(url, cookie); } }) .build(); // Build OkHttp request matching WebView's request Request okHttpRequest = new Request.Builder() .url(requestUrl) .headers(convertWebViewHeaders(request.getRequestHeaders())) .method(request.getMethod(), request.getMethod().equals("POST") ? RequestBody.create(null, new byte[0]) : null) .build(); try { Response okHttpResponse = client.newCall(okHttpRequest).execute(); // Analyze the response here: inspect headers, body, status code, etc. analyzeResponse(okHttpResponse); // Convert OkHttp response to WebResourceResponse for WebView MediaType mediaType = okHttpResponse.body().contentType(); String mimeType = mediaType != null ? mediaType.type() : "text/html"; String encoding = mediaType != null ? mediaType.charset().name() : "UTF-8"; WebResourceResponse webResourceResponse = new WebResourceResponse( mimeType, encoding, okHttpResponse.body().byteStream() ); webResourceResponse.setResponseHeaders(convertOkHttpHeaders(okHttpResponse.headers())); webResourceResponse.setStatusCodeAndReasonPhrase(okHttpResponse.code(), okHttpResponse.message()); return webResourceResponse; } catch (IOException e) { e.printStackTrace(); // If something fails, let WebView handle the request normally return super.shouldInterceptRequest(view, request); } } // Let WebView handle non-target requests normally return super.shouldInterceptRequest(view, request); } // Helper: Convert WebView's request headers to OkHttp Headers private Headers convertWebViewHeaders(Map<String, String> webViewHeaders) { Headers.Builder builder = new Headers.Builder(); for (Map.Entry<String, String> entry : webViewHeaders.entrySet()) { builder.add(entry.getKey(), entry.getValue()); } return builder.build(); } // Helper: Convert OkHttp response headers to WebView-compatible map private Map<String, String> convertOkHttpHeaders(Headers okHttpHeaders) { Map<String, String> webViewHeaders = new HashMap<>(); for (int i = 0; i < okHttpHeaders.size(); i++) { webViewHeaders.put(okHttpHeaders.name(i), okHttpHeaders.value(i)); } return webViewHeaders; } // Your custom logic to identify requests to analyze private boolean isTargetRequest(String url) { return url.contains("your-target-path-or-domain"); // Adjust this condition } // Your analysis logic private void analyzeResponse(Response response) throws IOException { // Example: Log response body String body = response.body().string(); Log.d("ResponseAnalysis", "Body: " + body); // Reset the body stream since we read it response.newBuilder().body(ResponseBody.create(response.body().contentType(), body.getBytes())).build(); }
Notes for Option 1:
- Cookie Sync: Make sure to sync WebView's cookies to your HTTP client (like OkHttp) to ensure the request matches what WebView would send.
- POST Requests: The example handles basic POST requests; you may need to adjust it if the request has a body (extract the body from the original
WebResourceRequestif possible). - Error Handling: Always fall back to
super.shouldInterceptRequest()if your manual request fails, so WebView can load the content normally.
Option 2: Use onReceivedResponseHeaders for Header-Only Analysis
If you only need to inspect response headers (not the full body), you can skip intercepting the request entirely and use the onReceivedResponseHeaders callback in WebViewClient. This method triggers when WebView receives response headers from the server:
@Override public void onReceivedResponseHeaders(WebView view, WebResourceRequest request, WebResourceResponse response) { super.onReceivedResponseHeaders(view, request, response); // Analyze response headers here Map<String, String> headers = response.getResponseHeaders(); int statusCode = response.getStatusCode(); String mimeType = response.getMimeType(); Log.d("HeaderAnalysis", "URL: " + request.getUrl()); Log.d("HeaderAnalysis", "Status Code: " + statusCode); Log.d("HeaderAnalysis", "Headers: " + headers.toString()); }
Notes for Option 2:
- This method doesn't give you access to the response body, but it's much simpler since you don't have to replicate requests.
- It works for all requests WebView handles, so you can add filtering logic to focus on specific URLs.
内容的提问来源于stack exchange,提问作者Дмитро Яковлєв

