我正在从 Node.js 后端向外部网站 (mirror.codeforces.com) 发出 POST 请求。在 Postman 和 Node.js axios 响应中,我收到状态代码 302(我已设置 maxRedirects = 0),但响应标头明显不同。只有一个重定向,我需要从重定向响应中获取“set-cookie”标头。
这是邮递员响应标头(取自邮递员控制台):
Server: kittenx
Date: Wed, 04 Dec 2024 09:42:21 GMT
Content-Type: text/html;charset=UTF-8
Content-Length: 0
Connection: keep-alive
Cache-Control: private,no-cache,no-store,max-age=0,must-revalidate
Expires: -1
Pragma: no-cache
Set-Cookie: X-User-Sha1=63425e0090d62898166c5c9b81df08c303901c5a; Max-Age=31536000; Expires=Thu, 04-Dec-2025 09:42:21 GMT; Path=/
Set-Cookie: X-User=6bda2511d1276d70f78a12c28e42ba5fbc25832f53e1abe635d83f3b21edd64d6896ee63fb14fdf7; Max-Age=2592000; Expires=Fri, 03-Jan-2025 09:42:21 GMT; Path=/
Location: https://mirror.codeforces.com/
Strict-Transport-Security: max-age=86400
X-XSS-Protection: 1; mode=block
X-Frame-Options: sameorigin
X-Content-Type-Options: nosniff
X-Frontend: front932212
X-Trace-Id: y-03olMfFrxCP1aH8EDH80OcdPtU2g
Server-Timing: tid;desc="y-03olMfFrxCP1aH8EDH80OcdPtU2g",front;dur=0.596
这是 Node.js 响应标头(使用 res.headers 记录到终端):
Object [AxiosHeaders] {
server: 'kittenx',
date: 'Wed, 04 Dec 2024 10:17:35 GMT',
'content-length': '0',
connection: 'close',
location: '/',
'strict-transport-security': 'max-age=86400',
'x-xss-protection': '1; mode=block',
'x-frame-options': 'sameorigin',
'x-content-type-options': 'nosniff',
'x-frontend': 'front932210',
'x-trace-id': 'RGgdGL7Uq1IT4hKwR88b1pomn6HsBA',
'server-timing': 'tid;desc="RGgdGL7Uq1IT4hKwR88b1pomn6HsBA",front;dur=0.131'
}
这里是用于 post 请求的 Node.js 代码 + cookieString 和 Postman 代码,供参考。
Cookie 在 Postman 和浏览器中可见,并在其中设置,这些是在浏览器上看到的 Cookie 的属性。我期待在响应标头中找到
X-User-Sha1
和 X-User
。
PS:我无法确认POST请求是否成功。即使不成功的请求也有可能被重定向为 302,在这种情况下,Postman 请求成功而 Node.js 请求不成功的原因可能是什么?它们都有相同的标头和 cookie(如上图链接所示)。
PPS:在 Postman 中(自动重定向关闭),发出 POST 请求,然后删除 X-User-Sha1 和 X-User cookie,然后向网站主页发出 GET 请求。
主要观察结果:
下面是axios配置--
const axios = require('axios');
async function makeRequest() {
try {
const response = await axios({
method: 'POST',
url: 'https://mirror.codeforces.com',
// Your POST data here
maxRedirects: 0,
validateStatus: function (status) {
return status >= 200 && status <= 302; // Accept 302 as valid status
},
headers: {
'Accept': '*/*',
'User-Agent': 'Mozilla/5.0', // Match Postman's User-Agent
'Content-Type': 'application/json',
},
withCredentials: true, // Important for cookie handling
decompress: true, // Handle compression if present
});
console.log('Status:', response.status);
console.log('Headers:', response.headers);
// Extract cookies from headers
const cookies = response.headers['set-cookie'];
if (cookies) {
console.log('Cookies:', cookies);
}
return response;
} catch (error) {
if (error.response) {
console.error('Response error:', {
status: error.response.status,
headers: error.response.headers,
data: error.response.data
});
}
throw error;
}
}
主要差异和解决方案是:
-- 添加 withCredentials: true 以启用正确的 cookie 处理 如果需要持久性 cookie,请使用 axios-cookiejar-support 包 处理:
{ wrapper } = require('axios-cookiejar-support');
const { CookieJar } = require('tough-cookie');
const jar = new CookieJar();
const client = wrapper(axios.create({ jar }));
-- 确保您的标头与 Postman 的标头完全匹配,尤其是用户代理 某些服务器根据用户代理做出不同的响应
-- 设置 maxRedirects: 0 以防止自动跟随重定向 使用 validateStatus 接受 302 作为有效状态代码
-- 检查response.headers['set-cookie'] 和response.headers['Set- Cookie'](区分大小写) -- 某些服务器可能仅在特定条件下发送 cookie(例如 认证成功)
如果您仍然没有收到cookie,您可以尝试:
比较发送的确切请求:
Add this to see the exact request configuration
axios.interceptors.request.use(request => {
console.log('Request:', JSON.stringify(request, null, 2));
return request;
});
使用 Charles 或 Fiddler 等调试代理来比较 Postman 和 axios 之间的原始 HTTP 流量 检查服务器是否有不同的响应:
IP地址 请求时间 先前的请求/会话状态 SSL/TLS 版本或密码套件
希望这有帮助。