Node.js request请求返回空响应体问题求助
先把你的代码整理出来(注意到你最后console.log(ht...应该是打错了变量名):
var request = require('request'); var j = request.jar(); request = request.defaults({jar:j, followAllRedirects: true}); var urls =new Array(); urls["login"] = "https://www.brooklynfitzone.com/index.php/login"; urls["main"] = "https://www.brooklynfitzone.com/index.php"; urls["reserva"] = "https://www.brooklynfitzone.com/index.php/classes/set_book"; // login request.post(urls["login"], {form:{user:'user@user.com',pass:'testpass'}}, function(err, httpResponse, html) { console.log(html); // 这里应该是html而不是未写完的ht... });
接下来逐一分析可能导致空响应体的原因:
变量名拼写错误:你代码里最后写的
console.log(ht...明显没写完,应该是console.log(html),如果是拼写错误,会导致打印undefined,看起来像是空响应体,先检查这个低级错误。请求本身失败但没处理错误:回调里第一个参数是
err,你完全没判断它。先在回调开头加上错误判断:if (err) { console.error('请求出错:', err); return; }同时打印响应状态码:
console.log('响应状态码:', httpResponse.statusCode),如果状态码是4xx/5xx,说明请求没成功,服务器可能没返回内容。缺少CSRF令牌等必要参数:很多网站的登录接口会要求CSRF令牌,你直接传user和pass大概率会被拒绝。先访问登录页面(urls["login"]),从页面的HTML里提取CSRF令牌(通常在form的隐藏input里,name可能是_csrf、token之类的),然后把这个参数加到form数据里一起提交。
请求头缺失被拦截:默认request的User-Agent是类似
request/2.88.2的标识,很多网站会识别这种非浏览器请求并拦截。你需要设置一个浏览器的User-Agent头:request.post(urls["login"], { headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36' }, form:{user:'user@user.com',pass:'testpass', _csrf: '提取到的令牌'} }, function(err, httpResponse, html) { // ... });request库已废弃的兼容性问题:request库早在2020年就停止维护了,可能和新版本Node.js存在兼容性问题,导致响应处理异常。如果上面的方法都不行,建议换成
axios或者node-fetch这类活跃维护的库,比如用axios实现相同逻辑:const axios = require('axios'); const cookieJar = new axios.CookieJar(); const instance = axios.create({ jar: cookieJar, withCredentials: true, followRedirects: true, headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36' } }); // 先获取CSRF令牌 instance.get(urls["login"]).then(res => { // 从res.data里提取csrf令牌 const csrfToken = res.data.match(/<input type="hidden" name="_csrf" value="([^"]+)"/)[1]; // 登录 return instance.post(urls["login"], { user: 'user@user.com', pass: 'testpass', _csrf: csrfToken }); }).then(res => { console.log('登录响应:', res.data); }).catch(err => { console.error('出错:', err); });编码问题导致响应体显示为空:如果服务器返回的是二进制数据或者特殊编码,request默认的编码可能解析错误,导致看起来是空。可以设置
encoding: null,然后手动处理:request.post(urls["login"], {form:{...}, encoding: null}, function(err, httpResponse, body) { const contentType = httpResponse.headers['content-type']; // 根据content-type解码,比如utf-8 const html = body.toString('utf-8'); console.log(html); });
内容的提问来源于stack exchange,提问作者monxas

