首页/网络/协议速查/CORS 预检请求流程
HTTP 头与缓存70 条

CORS 预检请求流程

非简单跨域请求前,浏览器先发 OPTIONS 预检:确认来源、方法与头都被允许后才发真实请求。

协议速查网络更新于 2026-10-13

CORS 预检是什么

同源策略默认禁止页面跨域读取响应。当跨域请求「不够简单」时,浏览器会先发一条 OPTIONS 预检,问服务器「我来自 X,想用 PUT,并带这些头,允许吗」;只有收到明确的许可响应,浏览器才发真实请求。因此预检是浏览器主动发起的安全问询,而不是业务接口的一部分。

基本信息

触发条件方法非 GET/HEAD/POST,或 Content-Type 非三类简单类型,或带自定义头
预检报文OPTIONS + Origin + Access-Control-Request-Method + Access-Control-Request-Headers
通过条件返回 2xx 且带匹配的 Access-Control-Allow-*
缓存时长由 Access-Control-Max-Age 控制
规范WHATWG Fetch 标准(CORS)

三个关键响应头

响应头作用常见坑
Access-Control-Allow-Origin声明允许的来源带凭证时不能写 *
Access-Control-Allow-Methods列出允许的方法漏写 PATCH 会让部分接口整体不可用
Access-Control-Allow-Headers列出允许的请求头漏写自定义头(如 x-token)预检直接失败

一次完整预检

一次完整预检
OPTIONS /api/data HTTP/1.1
Origin: https://app.example.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: content-type, x-token

HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET, PUT, PATCH
Access-Control-Allow-Headers: content-type, x-token
Access-Control-Max-Age: 600
Vary: Origin

典型使用场景

  • 前后端分离部署:前端域名与 API 域名不同,所有写操作都要预检
  • 带自定义鉴权头(Authorization 或 x-token)的接口
  • 提交 JSON(Content-Type: application/json)的写接口
  • 使用 PUT/PATCH/DELETE 的 REST 接口
  • 需要携带 Cookie 的跨域请求,还要额外开 Allow-Credentials

排查顺序

  • 先读浏览器控制台的具体报错,它通常直接指明缺哪个响应头
  • 用 curl 手工发 OPTIONS 打后端,绕过浏览器确认服务端的真实响应
  • 检查是否被网关或鉴权中间件拦成 401/405,预检失败最常出在这一层
  • 确认反向代理把 OPTIONS 转发给了后端,而不是自己吞掉或重定向
  • 带凭证时确认 ACAO 是具体来源,且 Allow-Credentials 为 true
预检失败不等于接口故障:服务端日志里往往连真实请求都看不到,先解决 OPTIONS 的响应,再谈业务逻辑。

减少预检的手段

  • 能不用自定义头就不用,改由请求体字段携带信息,可退回简单请求
  • Content-Type 尽量使用简单类型,代价是请求体的表达力下降
  • 把 Access-Control-Max-Age 设到浏览器允许的上限附近,减少重复预检
  • 同域部署或用同域路径反向代理,从架构上绕开跨域问题

易错点

  • 网关把 OPTIONS 当无效请求拦掉(401/405),跨域功能整体不可用,而接口本身完全正常
  • Access-Control-Max-Age 配得过短,每个业务请求前都多一次预检,后端压力悄悄翻倍
  • Allow-Credentials 为 true 却仍用通配符 ACAO,浏览器直接拒绝该响应,控制台只报一句笼统错误
  • 只给成功响应加 CORS 头,错误响应不带,前端拿不到错误详情,用户只看到「网络错误」

数据来源与参考

  • WHATWG Fetch 标准(CORS-preflight)
  • MDN:CORS 预检请求

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌