Selenium登录后Java发送带payload的POST请求获取接口数据问题
问题原因与解决方案
错误原因说明
- 单独使用
java.net.HttpClient请求失败:该客户端完全独立于你已经登录的Selenium Chrome会话,没有携带登录态Cookie、CSRF校验令牌等身份信息,属于匿名请求,因此站点返回错误页面。 - Selenium
HttpRequest类使用错误:该类是Selenium 4 DevTools API的配套数据结构,无法独立执行请求,需要绑定当前已打开的DevTools会话才能使用,配置成本较高。 JavascriptExecutor执行XHR失败:- 请求头配置错误,你设置的
XHR不是合法请求头键,正确的内容类型头键为Content-Type - 请求Payload错误,你已经通过Selenium完成站点登录,不需要再传递账号密码参数,需要和Chrome开发者工具中捕获的请求Payload完全一致
- 缺少Polar站点要求的CSRF校验头,这类站点都会校验请求的
X-CSRF-Token头避免跨站请求伪造。
- 请求头配置错误,你设置的
最优实现方案(基于JavascriptExecutor,无需额外配置)
你已经通过Selenium持有了站点的登录态,直接在当前页面上下文执行JS发请求是成本最低的方案,直接替换你之前的JS代码即可:
- 先从Chrome开发者工具对应请求的「Payload」标签页,复制完整的表单请求体内容
- 使用以下代码执行请求:
JavascriptExecutor js = (JavascriptExecutor) driver; // 提取页面内置的CSRF令牌 String csrfToken = (String) js.executeScript("return document.querySelector('meta[name=\"csrf-token\"]').content;"); // 替换为你从开发者工具复制的完整请求体 String requestPayload = "fromDate=2024-01-01&toDate=2024-06-30"; // 发起同步XHR请求 String apiResponse = (String) js.executeScript( "const xhr = new XMLHttpRequest();" + "xhr.open('POST', 'https://flow.polar.com/api/training/history', false);" + "xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');" + "xhr.setRequestHeader('X-CSRF-Token', arguments[0]);" + "xhr.send(arguments[1]);" + "return xhr.responseText;", csrfToken, requestPayload ); System.out.println(apiResponse);
可选方案(基于HttpClient)
如果你坚持使用独立的HttpClient发起请求,需要先将Selenium会话中的所有Cookie导出,再配置到HttpClient的请求中,同时也要携带正确的CSRF头和请求Payload,步骤如下:
- 导出Selenium会话中的Cookie:
Set<Cookie> seleniumCookies = driver.manage().getCookies();
- 构建HttpClient请求时,将所有Cookie添加到请求头的
Cookie字段中,同时配置和浏览器一致的User-Agent、Content-Type、X-CSRF-Token头以及正确的Payload即可。
内容的提问来源于stack exchange,提问作者mousekip
相关产品推荐
相关产品推荐

