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

React应用CORS请求后Cookie丢失,原生JS正常问题排查

问题

React应用中执行以下CORS fetch请求:

const response = await fetch("http://localhost:3000/users/sign_in", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    credentials: "include",
  },
  body: JSON.stringify({ user: { email, password } }),
});

服务器响应包含如下头部信息(第二个Cookie内容已截断,但参数与第一个一致):

Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD
Access-Control-Allow-Origin: http://localhost:3001
Access-Control-Expose-Headers:
Access-Control-Max-Age: 7200
Cache-Control: max-age=0, private, must-revalidate
Content-Type: application/json; charset=utf-8
Etag: W/"36cb9f6def08029b9c6bff3c14a98017"
Referrer-Policy: strict-origin-when-cross-origin
Server-Timing: sql.active_record;dur=23.10, start_processing.action_controller;dur=0.27, instantiation.active_record;dur=6.83, process_action.action_controller;dur=274.12
Set-Cookie: CSRF-TOKEN=UrU9vCDa-ni5ZWXUOIgaEEeGL4izouMAEFpa3oJWTH0dAUOIUH5yZDEogo9opprqe6r3YEoMxl0w4aT18zvIMQ; path=/; secure; SameSite=None
Set-Cookie: _session_id=4Aj5KMcZZG0Bn7EL4hhfdZHt0rw6WX46tpA9Lb8uE09apmDiALhiSAkGeUDIZuNvRJ9yTcUEbhydbFIgKYOkNPcMXrz7wItdWWjJSVsy%2Bfrp43uTxALrEsxVI%2BrvHrqfUTkM2FyP9MhqI8X1GPvbuIge%2FF4Acapi%2FuyPrmOqn9MMNqwqyJA%2Fo8GjtaU7vb4GzhDVxWOUQuVmKHm%2BCw2wGB4GsH%2Bv0QO1C%2BOYZE2PTVfeuONCWaXchyY21C0MVFnYYsZ2eB48c2

遇到的异常情况:

  • Chrome开发者工具中无法找到这些Cookie
  • 完全相同的代码、服务器、浏览器及CORS配置,在原生JS环境(无React)中可正常设置并携带Cookie
  • 网络请求(含预检)完全一致,仅React环境下Cookie丢失
  • Cookie符合Chrome规范(SameSite=None+secure=true),请求已成功返回Cookie
分析与解决

1. fetch配置错误(最可能原因)

你的代码把credentials: "include"错误放在了headers对象里,这不符合fetch API规范——credentials是fetch配置的顶级选项,不属于headers范畴。

原生JS环境中浏览器可能兼容了这个错误,但React环境下(结合开发工具的严格检查),该错误会导致浏览器无法正确处理跨域凭据,进而无法保存Cookie。

修正后的代码:

const response = await fetch("http://localhost:3000/users/sign_in", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  credentials: "include", // 移至顶级配置
  body: JSON.stringify({ user: { email, password } }),
});

2. React开发服务器代理干扰

如果你的React项目用create-react-app默认代理(package.json的proxy字段),代理服务器转发请求时会丢失Set-Cookie的部分属性,导致浏览器无法识别Cookie。

解决方法:

  • 直接关闭代理,让前端请求直连后端(确保前后端端口不同,如前端3001、后端3000)
  • 自定义代理配置(用http-proxy-middleware),明确保留Set-Cookie头部:
    // src/setupProxy.js
    const { createProxyMiddleware } = require('http-proxy-middleware');
    
    module.exports = function(app) {
      app.use(
        '/users',
        createProxyMiddleware({
          target: 'http://localhost:3000',
          changeOrigin: true,
          onProxyRes: (proxyRes, req, res) => {
            const cookies = proxyRes.headers['set-cookie'];
            if (cookies) res.setHeader('Set-Cookie', cookies);
          }
        })
      );
    };
    

3. Secure Cookie的环境限制

Cookie设置了secure属性,Chrome允许localhost下HTTP请求使用该Cookie,但React开发环境的Service Worker拦截、请求转发等机制可能让浏览器误判环境为非安全,拒绝保存Cookie。

解决方法:

  • 开发环境临时移除secure属性(生产环境必须恢复)
  • 将React开发服务器切换为HTTPS模式,修改package.json启动命令:
    "scripts": {
      "start": "HTTPS=true react-scripts start"
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 01:19:56