React中POST请求为什么被CORS拦截?预检请求没发出去?

慕容雨萱 阅读 3

在React项目里用fetch发POST请求到第三方API时,浏览器突然报CORS错误。我明明设置了headers里的Content-Type为application/json,但控制台显示”Response to preflight request doesn’t pass access control check”。

试过在headers加mode: ‘cors’和credentials: ‘omit’,但问题依旧。奇怪的是同样的代码在本地测试环境没问题,部署到生产环境就拦截了。难道预检请求没发出去?代码如下:


const sendRequest = async () => {
  try {
    const response = await fetch('https://api.example.com/data', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ' + token
      },
      body: JSON.stringify({ name: 'test' })
    });
    return response.json();
  } catch (error) {
    console.error('CORS error:', error);
  }
};

检查Network面板发现只有POST请求被拦截,没有看到OPTIONS预检请求。生产服务器是Nginx配置的,是不是需要特别开启预检支持?

我来解答 赞 3 收藏
二维码
手机扫码查看
1 条解答
爱学习的颖杰
这个问题其实是CORS预检请求的典型问题,先分析一下原因。你提到生产环境有问题,但本地没问题,这基本可以确定是服务器端的CORS配置差异导致的。浏览器在发POST请求之前会先发一个OPTIONS请求来确认服务器是否允许跨域访问,这个叫预检请求。如果预检请求没通过,浏览器直接拦截后续的POST请求。

从你的描述来看,生产环境用的是Nginx,很可能是Nginx没有正确处理OPTIONS请求,或者响应头里缺少必要的CORS字段。你可以按照以下步骤排查和解决:

先检查一下Nginx的配置文件,确保它能正确处理OPTIONS请求。可以在server块里加上类似下面的配置:


if ($request_method = OPTIONS) {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods GET, POST, OPTIONS;
add_header Access-Control-Allow-Headers Authorization, Content-Type;
return 204;
}


这段配置的意思是,当收到OPTIONS请求时,直接返回204状态码,并添加必要的CORS响应头。

然后,再检查一下Nginx对其他请求的CORS支持,确保每个正常的请求也带上这些响应头。比如:


add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods GET, POST, OPTIONS;
add_header Access-Control-Allow-Headers Authorization, Content-Type;


另外,如果你的服务端用了反向代理,确保代理层不会把OPTIONS请求过滤掉或者改写。有时候代理层会默认丢弃非GET/POST请求,这就导致预检请求根本到不了后端。

最后,补充一点,你在fetch里加的mode: 'cors'其实是多余的,因为fetch默认就是cors模式。而credentials: 'omit'可能会导致某些需要认证的接口出问题,建议去掉试试。

改完Nginx配置后记得重启服务:sudo nginx -s reload,然后清空浏览器缓存再试一次。如果还是有问题,可以用curl命令手动模拟一个OPTIONS请求,看看返回的响应头是不是符合预期。比如这样:


curl -X OPTIONS -H "Origin: http://your-react-app.com" -H "Access-Control-Request-Method: POST" -H "Access-Control-Request-Headers: Authorization, Content-Type" https://api.example.com/data -I


总之,重点是让Nginx正确处理OPTIONS请求并返回合适的CORS头。搞定这个,问题应该就解决了。
点赞
2026-02-19 15:00