You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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请求

我们需要通过WebViewClientshouldInterceptRequest方法拦截目标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

火山引擎 最新活动