NodeJS Express中两种CORS预检请求处理代码有何区别
两种CORS配置的具体差异
你提到的两种写法核心区别在于预检请求(OPTIONS请求)的处理逻辑,二者并不等价:
- 官方推荐方案(
app.use(cors()); app.options('*', cors());)的逻辑:- 第一行
app.use(cors())作为全局中间件,会给所有非预检的普通请求自动注入符合CORS规范的响应头,默认配置下允许所有源跨域,同时会自动适配请求携带的跨域相关头返回对应配置。 - 第二行专门拦截所有路径的OPTIONS预检请求,交给cors中间件处理:中间件会自动根据请求的
Access-Control-Request-Method、Access-Control-Request-Headers字段返回匹配的Access-Control-Allow-Methods、Access-Control-Allow-Headers响应头,自动返回规范要求的204状态码并结束响应,不会让预检请求流转到后续业务路由,默认还会带上Access-Control-Max-Age等优化缓存的头,兼容性覆盖完整。
- 第一行
- 教程给出的手动配置方案的逻辑:
- 第一行全局cors中间件的逻辑和官方方案完全一致,差异在OPTIONS请求的处理上:
- 所有CORS响应头都是硬编码写死的:允许方法只覆盖了GET/PUT/POST/OPTIONS,后续如果用DELETE、PATCH等方法会直接跨域失败;允许头只写了三个固定字段,前端传
Content-Type: application/json或者其他自定义请求头时都会被浏览器拦截。 - 固定返回
Access-Control-Allow-Origin: *,后续如果要做带Cookie的跨域请求(需要配置具体源,不能用通配符),得全量修改这段逻辑。 - 代码里设置完响应头之后没有调用
res.end()或者res.sendStatus(204)结束响应,请求会继续向后匹配路由,很容易走到404或者其他业务逻辑里,导致预检请求失败。 - 没有做任何CORS规范的兼容处理,很容易出现各种边界case的跨域报错。
- 所有CORS响应头都是硬编码写死的:允许方法只覆盖了GET/PUT/POST/OPTIONS,后续如果用DELETE、PATCH等方法会直接跨域失败;允许头只写了三个固定字段,前端传
- 第一行全局cors中间件的逻辑和官方方案完全一致,差异在OPTIONS请求的处理上:
对你的猜想的验证
你认为app.options('*', cors())和手动设置res.header("Access-Control-Allow-Origin", "*")效果等价的判断是错误的。
手动设置单个允许源头只完成了CORS预检响应的极小一部分工作,
cors()中间件封装了所有CORS规范要求的校验、头返回、响应结束逻辑,硬编码头的写法只适合接口固定、无扩展需求的临时测试场景,生产环境或者长期维护的项目直接用cors中间件处理OPTIONS请求是更稳妥的选择。
内容的提问来源于stack exchange,提问作者Michael Vigato
相关产品推荐
相关产品推荐

