为什么设置了Access-Control-Allow-Methods后OPTIONS请求还是被拦截?

上官宇轩 阅读 50

我在前端用fetch发POST请求时,明明在服务器设置了”Access-Control-Allow-Methods: POST”,但浏览器还是报错说方法不允许。预检OPTIONS请求返回405状态码,控制台提示:


fetch('https://api.example.com/data', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ name: 'test' })
})
.then(response => console.log(response))
.catch(err => console.error('请求失败:', err));

我检查过服务器响应头确实有Access-Control-Allow-Methods字段,但为什么还是被拦截?难道这个头需要配合其他配置?

我来解答 赞 10 收藏
二维码
手机扫码查看
2 条解答
博主郭云
OPTIONS请求被拦截是因为服务器没正确处理预检请求,光设置Access-Control-Allow-Methods不够,还得确保服务器允许OPTIONS方法并正确返回200状态码。

以Node.js为例,关键代码如下:
const express = require('express');
const app = express();

app.options('/data', (req, res) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'POST');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
res.status(200).send();
});

app.post('/data', (req, res) => {
res.json({ success: true });
});

app.listen(3000, () => console.log('服务启动'));


检查你的服务器是否正确响应了OPTIONS请求,尤其是状态码和CORS头。「就这样」
点赞 1
2026-02-18 11:13
慕容世豪
你遇到这个问题是因为浏览器在发跨域POST请求时,会先发起一个OPTIONS预检请求,确认服务器允许的请求方法和头信息。仅仅设置Access-Control-Allow-Methods是不够的,还需要正确处理OPTIONS请求本身。

问题出在服务器端对OPTIONS请求的响应上。当浏览器发送OPTIONS请求时,服务器直接返回了405状态码(Method Not Allowed),说明服务器没有正确配置来处理这个预检请求。

解决方法很简单,在服务器端做以下调整:
1. 确保服务器能够正确响应OPTIONS请求,并返回200状态码
2. 在响应头中加入Access-Control-Allow-Methods: POST, OPTIONS(注意包含OPTIONS)
3. 同时添加Access-Control-Allow-Headers: Content-Type,因为你的请求带了自定义头

举个栗子,如果你用的是Node.js + Express,可以这么写:
app.use((req, res, next) => {
if (req.method === 'OPTIONS') {
res.header('Access-Control-Allow-Methods', 'POST, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type');
return res.status(200).send('');
}
next();
});


最后提醒一下,浏览器兼容性在这里一般不会出问题,主要是服务器端要正确处理预检请求。不然即使前端代码没问题,也会被拦截。
点赞 7
2026-02-01 15:08