Android WebView中如何为POST请求添加自定义请求头与请求体?
解决Android WebView POST请求添加自定义请求头与请求体的方案
嗨,我来帮你搞定这个WebView的POST请求问题!你已经找到了添加请求头的方法,只差请求体的正确实现,咱们一步步来:
先提个关键注意点
你设置的请求头是Content-Type: application/x-www-form-urlencoded,但代码里用了JSONObject来构建请求体——这俩格式不匹配哦!application/x-www-form-urlencoded要求请求体是key1=value1&key2=value2的键值对格式,而非JSON字符串,服务器大概率没法正确解析JSON格式的请求体,所以第一步要先把参数转成正确的格式。
具体实现步骤
1. 构建符合要求的请求体
把你的参数转换成URL编码后的键值对字符串,再转成字节数组(postUrl()方法需要字节数组格式的请求体):
import java.net.URLEncoder; import java.nio.charset.StandardCharsets; // 构建URL编码后的键值对参数 String postData = String.format( "Signature=%s&Token=%s&Timestamp=%s&ServiceCardNumber=%s&DriverFirstName=%s", URLEncoder.encode(signature, "UTF-8"), URLEncoder.encode(token, "UTF-8"), URLEncoder.encode(timestamp, "UTF-8"), URLEncoder.encode(svcCardNo, "UTF-8"), URLEncoder.encode(person_first_name, "UTF-8") ); // 转成字节数组,供postUrl使用 byte[] postDataBytes = postData.getBytes(StandardCharsets.UTF_8);
一定要给参数值做URL编码,避免特殊字符(比如空格、&、=)导致请求解析失败。
2. 配置WebView,添加自定义请求头并发送POST请求
我们需要通过WebViewClient的shouldInterceptRequest方法拦截目标POST请求,手动添加自定义请求头,再发送请求并把响应返回给WebView:
WebView webView = findViewById(R.id.your_webview_id); WebSettings webSettings = webView.getSettings(); webSettings.setJavaScriptEnabled(true); // 根据你的需求开启JS,表单预填充可能需要 webView.setWebViewClient(new WebViewClient() { @Override public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) { // 只拦截我们目标的POST请求 String targetUrl = "https://submittest.glassclaim.com/SelfService/Default.aspx?ClientTag=4E7B1611-E22A-4B38-9651-006CF6DFD71A"; if (targetUrl.equals(request.getUrl().toString()) && request.getMethod().equalsIgnoreCase("POST")) { try { // 构建HttpURLConnection来发送带自定义头的请求 URL url = new URL(targetUrl); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); // 添加自定义请求头 connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); // Content-Length一般会自动计算,如果你一定要手动设置的话: // connection.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length)); // 设置请求方法为POST,允许写入请求体 connection.setRequestMethod("POST"); connection.setDoOutput(true); // 写入请求体数据 OutputStream outputStream = connection.getOutputStream(); outputStream.write(postDataBytes); outputStream.flush(); outputStream.close(); // 获取服务器响应,返回给WebView加载 InputStream inputStream = connection.getInputStream(); String mimeType = connection.getContentType(); String encoding = connection.getContentEncoding(); return new WebResourceResponse(mimeType, encoding, inputStream); } catch (IOException e) { e.printStackTrace(); } } // 其他请求交给WebView默认处理 return super.shouldInterceptRequest(view, request); } }); // 触发POST请求 webView.postUrl(targetUrl, postDataBytes);
3. 额外注意事项
- 权限配置:别忘了在
AndroidManifest.xml里添加网络权限:<uses-permission android:name="android.permission.INTERNET" /> - 版本兼容:
shouldInterceptRequest(WebView, WebResourceRequest)是Android 5.0(API 21)及以上的方法,如果要兼容更低版本,可以重写shouldInterceptRequest(WebView, String),不过后者的功能会有限制。 - 若需JSON请求体:如果你其实需要发送JSON格式的请求体,那要把
Content-Type改成application/json,请求体直接用jsonObjForReqBody.toString()转成字节数组即可。
这样配置后,WebView就能发送带自定义请求头和正确格式请求体的POST请求,服务器应该就能正确解析并返回预填充好的表单页面了。
内容的提问来源于stack exchange,提问作者Menu




