带请求体的Axios POST请求触发CORS错误求助
解决带请求体的POST请求CORS错误
问题根源
带请求体的POST请求会触发浏览器的预检OPTIONS请求,你的后端只在POST路由里设置了Access-Control-Allow-Origin头,但没有处理OPTIONS请求,导致预检请求返回的响应缺少CORS头,浏览器直接拦截了后续的POST请求。而不带请求体的POST请求属于简单请求,不会触发预检,所以能正常返回。
解决方案
方案1:使用Express官方推荐的cors中间件(最简便)
- 安装cors包:
npm install cors
- 在你的Express应用中全局引入并使用,或者在特定路由使用:
// 全局使用(推荐,所有路由都能处理CORS) const express = require('express'); const cors = require('cors'); const app = express(); app.use(cors()); // 允许所有跨域请求,生产环境可配置特定origin // 或者在特定路由使用 const router = express.Router(); router.use(cors()); router.post("/filterlist", function (req, res, next) { func.getFilteredList(req.body, (result) => { res.send(result); }); });
方案2:手动处理OPTIONS请求并设置完整CORS头
如果不想用第三方包,可以手动添加中间件处理OPTIONS请求,并设置必要的CORS头:
// 全局CORS中间件,处理所有OPTIONS和其他请求 app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', '*'); res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE'); res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization'); // 处理预检OPTIONS请求,直接返回200 if (req.method === 'OPTIONS') { return res.sendStatus(200); } next(); }); // 你的POST路由不需要再单独设置头 router.post("/filterlist", function (req, res, next) { func.getFilteredList(req.body, (result) => { res.send(result); }); });
验证说明
使用以上任意方案后,浏览器的预检OPTIONS请求会得到正确的CORS头响应,后续带请求体的POST请求就能正常执行。Postman能正常请求是因为它不会发送预检OPTIONS请求,直接发送POST,所以之前能拿到结果。
内容的提问来源于stack exchange,提问作者Yukio
相关产品推荐
相关产品推荐

