如何从WebResourceRequest获取请求体?相关方案是否有更新?
从WebResourceRequest获取请求体的可行方案
嘿,这个问题我之前也踩过坑!先给你明确一个核心事实:从Android官方提供的WebResourceRequest API本身,不管是现在还是你之前查资料的时候,都没有直接获取请求体的方法——这是WebView安全设计的一部分,请求体属于敏感数据,官方默认不对外暴露。
不过也不是完全没办法,根据不同场景,有两个比较靠谱的解决方案:
方案一:替换WebView的网络栈为OkHttp(通用第三方网页场景)
如果是你无法控制的第三方网页,最稳妥的方式是把WebView的默认网络请求换成OkHttp处理,这样就能通过OkHttp的拦截器拿到请求体了:
- 先创建带拦截器的OkHttpClient,在拦截器里读取请求体:
OkHttpClient okHttpClient = new OkHttpClient.Builder() .addInterceptor(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); // 只处理POST请求(GET请求本来就没有请求体) if ("POST".equalsIgnoreCase(request.method())) { // 读取请求体内容 Buffer buffer = new Buffer(); request.body().writeTo(buffer); String requestBodyContent = buffer.readUtf8(); // 这里就拿到请求体了,你可以做日志、校验等操作 } return chain.proceed(request); } }) .build();
- 重写WebViewClient的
shouldInterceptRequest方法,把WebView的请求转交给OkHttp处理:
@Override public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) { try { // 用OkHttp发送请求 Request okRequest = new Request.Builder() .url(request.getUrl().toString()) .headers(Headers.of(request.getRequestHeaders())) .method(request.getMethod(), request.getMethod().equals("POST") ? RequestBody.create(null, new byte[0]) : null) // 占位,实际请求体由拦截器处理 .build(); Response okResponse = okHttpClient.newCall(okRequest).execute(); // 将OkHttp的Response转为WebResourceResponse返回给WebView return new WebResourceResponse( okResponse.header("Content-Type", "text/plain"), okResponse.header("Content-Encoding", "utf-8"), okResponse.body().byteStream() ); } catch (IOException e) { e.printStackTrace(); return super.shouldInterceptRequest(view, request); } }
方案二:通过JSBridge传递请求体(自有H5场景)
如果这个WebView加载的是你自己开发的H5页面,那这个方法更简单:在H5发送请求前,通过JavaScriptInterface把请求体数据传递给Native层。
- 先给WebView添加JS接口:
webView.addJavascriptInterface(new Object() { @JavascriptInterface public void passRequestBody(String url, String method, String body) { // 这里直接拿到H5传递过来的请求体、请求地址和方法 Log.d("WebRequest", "Request Body: " + body); } }, "NativeBridge");
- 在H5的请求逻辑里,发送请求前调用Native接口:
// 比如用fetch发送请求前 const requestBody = JSON.stringify({key: "value"}); window.NativeBridge.passRequestBody("https://your-api.com", "POST", requestBody); fetch("https://your-api.com", { method: "POST", body: requestBody });
关于API变化的说明
从Android 5.0(API 21)引入WebResourceRequest到现在,官方的API设计一直没有改变——始终没有提供直接获取请求体的方法。所以你之前查资料得到的结论,放到现在依然成立,只是我们可以通过上述替代方案绕开这个限制。
内容的提问来源于stack exchange,提问作者Arya
相关产品推荐
相关产品推荐

