为什么浏览器发了 OPTIONS 请求却没发真正的 POST 请求?

シ利君 阅读 19

我用 fetch 发一个跨域 POST 请求,结果只看到浏览器自动发了个 OPTIONS 预检请求,但后续的 POST 根本没发出去。后端也确认没收到 POST,控制台也没报错,就是卡住了。我试过加 headers,但好像还是不行。

这是我的代码:

fetch('https://api.example.com/upload', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ name: 'test' })
})
.then(res => res.json())
.then(data => console.log(data));
我来解答 赞 3 收藏
二维码
手机扫码查看
1 条解答
打工人怡玥
啊这个问题我之前也碰到过,挺烦人的!这其实是CORS(跨域资源共享)的问题,浏览器在发送某些跨域请求时会先发OPTIONS预检请求,如果预检没通过就不会发真正的POST。

你的代码里Content-Type: application/json这个header会触发预检请求。要解决的话,通常需要后端配合:

1. 后端需要在OPTIONS请求的响应里包含这些header:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, OPTIONS
Access-Control-Allow-Headers: Content-Type


2. 或者如果你能控制前端代码,可以试试改成简单请求(不会触发预检):
fetch('https://api.example.com/upload', {
method: 'POST',
body: JSON.stringify({ name: 'test' })
})

去掉自定义header,让Content-Type默认变成text/plain就不会触发预检了。

如果还是不行的话,八成是后端没正确响应OPTIONS请求,可以打开浏览器开发者工具的Network标签看看OPTIONS请求的响应头里有没有上面说的那几个CORS相关的header。
点赞 2
2026-03-08 21:02