Access-Control-Allow-Methods 设置后为什么 OPTIONS 请求还是失败?

设计师新玲 阅读 7

我在前端用 fetch 发了个 POST 请求到后端接口,但浏览器先发了个 OPTIONS 预检请求,结果返回 405。后端明明在响应头里加了 Access-Control-Allow-Methods: POST, GET, OPTIONS,为啥还是不行?

我试过在 Nginx 里配这个头,也试过后端代码里手动设置,但 OPTIONS 请求始终被拒绝。是不是还要额外处理 OPTIONS 请求本身?

fetch('https://api.example.com/data', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ foo: 'bar' })
})
我来解答 赞 3 收藏
二维码
手机扫码查看
1 条解答
端木沐阳
问题不在响应头,而是你的服务器根本没处理OPTIONS请求。浏览器发OPTIONS过来,你后端要么没写对应的路由处理,要么返回了405。

后端得专门接收OPTIONS请求并返回200:

# 如果用Flask
@app.route('/data', methods=['OPTIONS'])
def handle_options():
response = make_response()
response.headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS'
response.headers['Access-Control-Allow-Headers'] = 'Content-Type' return response, 200

# 如果用Express
app.options('/data', (req, res) => {
res.set('Access-Control-Allow-Methods', 'POST, GET, OPTIONS');
res.set('Access-Control-Allow-Headers', 'Content-Type');
res.sendStatus(200);
});


Nginx里也得保证OPTIONS不被拒绝:

location / {
# 预检请求直接返回200和头
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Methods' 'POST, GET, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Content-Type';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain';
add_header 'Content-Length' 0;
return 204;
}
# 正常请求继续
proxy_pass http://backend;
}


总之:Access-Control-Allow-Methods是告诉浏览器能用什么方法,但你得先让OPTIONS请求活着回来,浏览器才能读到这些头。
点赞
2026-03-12 13:00