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

使用HttpURLConnection发起POST请求遇"过时浏览器"提示问题求助

解决HttpURLConnection二次请求返回"过时浏览器"提示的问题

问题背景

我在用Java的HttpURLConnection开发应用时碰到了个头疼的问题:

  • 先向目标站点发送POST请求获取token,这一步一切正常
  • 拿着拿到的token向同一站点的另一个接口发起第二次POST请求,虽然返回状态码是200,但响应内容却提示"您正在使用过时浏览器,请更新浏览器"
  • 已经尝试修改了User-Agent字段,但问题还是没解决

首次请求代码

String parameters="parameter=example1";
URL url = new URL("http://example1");
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length", parameters + Integer.toString(parameters.getBytes().length));
conn.setRequestProperty("Content-Language", "en-US");
conn.setRequestProperty("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
conn.setRequestProperty("User-Agent","Mozilla/5.0 ");
conn.setUseCaches(false);
conn.setDoInput(true);
conn.setDoOutput(true);

第二次请求代码

String parameters1="paramters=example2&token="+token;
URL url1 = new URL("https://example1/form");
HttpURLConnection conn1 = (HttpURLConnection)url1.openConnection();
conn1.setRequestMethod("POST");
conn1.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
conn1.setRequestProperty("Content-Length", parameters1 + Integer.toString(parameters1.getBytes().length));
conn1.setRequestProperty("Content-Language", "en-US");
conn1.setRequestProperty("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
conn1.setRequestProperty("User-Agent","Mozilla/5.0");

第二次请求响应头

Status 200
Server: Apache-Example/1.1
Content-Type: text/html;charset=UTF-8
Content-Language: en-US
Cteonnt-Length: 6923
Cneonction: close
Date: Sat, 27 Jan 2018 13:23:53 GMT
Connection: keep-alive
Vary: Accept-Encoding
Set-Cookie: JSESSIONID=example; Path=/;
X-Android-Sent-Millis: 1517059396002
X-Android-Received-Millis: 1517059396187
X-Android-Response-Source: NETWORK 200


问题分析与解决方案

我整理了几个最可能的原因和对应的解决办法,你可以逐一尝试:

1. 未携带会话Cookie(最核心原因)

从响应头能看到服务器返回了JSESSIONID,这是会话标识。第一次请求后服务器已经为你创建了会话,但第二次请求没携带这个Cookie,服务器会认为是新的陌生请求,触发浏览器检测。

  • 第一次请求完成后,获取响应头里的Set-Cookie值保存起来
  • 第二次请求时,在请求头里添加Cookie字段,把保存的值传进去

示例代码:

// 第一次请求后提取Cookie
String sessionCookie = conn.getHeaderField("Set-Cookie");

// 第二次请求时添加Cookie
conn1.setRequestProperty("Cookie", sessionCookie);

2. Content-Length设置错误

你代码里的Content-Length写法明显有问题,把参数字符串和长度拼在一起了,服务器根本无法正确解析请求体:

// 错误写法
conn.setRequestProperty("Content-Length", parameters + Integer.toString(parameters.getBytes().length));

改成正确的写法,直接传入请求体的字节长度:

byte[] postData = parameters.getBytes(StandardCharsets.UTF_8);
conn.setRequestProperty("Content-Length", Integer.toString(postData.length));

3. User-Agent过于简陋

单纯的Mozilla/5.0太容易被识别为非真实浏览器,建议用一个完整的现代浏览器UA,比如:

conn1.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36");

4. 缺少必要的请求头

真实浏览器发送请求时还会携带Referer、Accept-Encoding等字段,你可以补充上这些头信息,让请求更接近真实浏览器行为:

conn1.setRequestProperty("Referer", "http://example1"); // 填写第一次请求的URL
conn1.setRequestProperty("Accept-Encoding", "gzip, deflate, br");
conn1.setRequestProperty("Connection", "keep-alive");

5. 请求体未正确发送

检查两次请求是否都正确写出了请求体,如果没发送请求体,服务器可能没有生成有效的token,或者会话不完整:

// 第一次请求发送请求体示例
OutputStream os = conn.getOutputStream();
os.write(postData);
os.flush();
os.close();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:37:40