CORS 中 Access-Control-Allow-Methods 设置后为啥还是报错?

皇甫建英 阅读 49

我前端用 fetch 发了个 DELETE 请求,但浏览器控制台一直报 CORS 错误,说 method 不被允许。后端明明已经加了 Access-Control-Allow-Methods: GET, POST, PUT, DELETE 啊,是不是我前端写法有问题?

这是我的请求代码:

fetch('/api/item/123', {
  method: 'DELETE',
  headers: {
    'Content-Type': 'application/json'
  }
})
.then(res => res.json())
.then(data => console.log(data));
我来解答 赞 7 收藏
二维码
手机扫码查看
2 条解答
Dev · 梓辰
这问题挺典型的,不是你前端写法的问题,是后端没处理好预检请求。

DELETE 请求配合 Content-Type: application/json 会触发 CORS 的预检机制(Preflight Request)。浏览器会先发一个 OPTIONS 请求来探路,确认服务端是否允许这个跨域请求。你后端只返回了 Allow-Methods,但 OPTIONS 请求本身没正确响应的话,浏览器就直接报错了。

你后端需要额外做两件事:

第一,OPTIONS 请求要能正常返回响应,不能返回 404 或者 405。

第二,Access-Control-Allow-Methods 里要把 OPTIONS 加进去:

// Node.js/Express 示例
app.options('/api/*', (req, res) => {
res.set('Access-Control-Allow-Origin', '*');
res.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
res.set('Access-Control-Allow-Headers', 'Content-Type');
res.sendStatus(200);
});

// 或者用 cors 中间件
app.use(cors({
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS']
}));


PHP 的话差不多:

header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type');

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(200);
exit;
}


简单说就是:别忘了处理 OPTIONS,把 OPTIONS 加到允许的方法列表里。官方文档里关于 CORS 预检的部分有详细说明,可以翻翻看。
点赞
2026-03-19 18:03
南宫秀花
你后端虽然加了 Access-Control-Allow-Methods: GET, POST, PUT, DELETE,但浏览器发 DELETE 请求时,默认会先发一个 OPTIONS 预检请求,这时候你后端必须对这个 OPTIONS 请求也返回正确的 CORS 头,尤其是 Access-Control-Allow-MethodsAccess-Control-Allow-Headers

你前端代码没问题,问题在后端没处理好预检请求。

直接用这个思路排查:

1. 先看 Network 面板里有没有 OPTIONS 请求,状态码是不是 200
2. 如果有 OPTIONS 请求,点开它看 Response Headers 里有没有:
- Access-Control-Allow-Origin
- Access-Control-Allow-Methods
- Access-Control-Allow-Headers(重点!你请求里带了 Content-Type: application/json,预检必须允许这个头)

比如 Node.js 的 Express 用这个中间件试试:

app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*')
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization')
if (req.method === 'OPTIONS') {
return res.status(200).end()
}
next()
})


Java Spring Boot 用 @CrossOrigin 注解也行,但要注意 @CrossOrigin(origins = "*", allowedHeaders = {"Content-Type", ...}, methods = {RequestMethod.DELETE, ...}) 要写全。

别光加 DELETE,预检请求里必须明确允许 Content-Type 这个头,否则浏览器直接拦掉,报错看起来像“method 不支持”,其实是 headers 不对。
点赞 6
2026-02-24 18:15