Postman 和 Node.js axios 中 302 响应的不同响应标头

问题描述 投票:0回答:1

我正在从 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 代码 + cookieStringPostman 代码,供参考。

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

node.js http-redirect axios postman http-status-code-302
1个回答
0
投票

主要观察结果:

  1. 主要区别在于 Postman 的响应包含 Set-Cookie 标头,而 axios 的响应则不包含。
  2. Location 标头值不同(完整 URL 与仅“/”)
  3. 两者都显示 302 状态代码,但处理重定向的方式可能不同

下面是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;
  }
}

主要差异和解决方案是:

  1. Cookie 处理:

-- 添加 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 }));
  1. 标题:

-- 确保您的标头与 Postman 的标头完全匹配,尤其是用户代理 某些服务器根据用户代理做出不同的响应

  1. 重定向处理:

-- 设置 maxRedirects: 0 以防止自动跟随重定向 使用 validateStatus 接受 302 作为有效状态代码

  1. 响应处理:

-- 检查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 版本或密码套件

希望这有帮助。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.