预检请求(Preflight Request)是浏览器在发送非简单跨域请求(CORS)前,自动发起的一次试探性请求,用于确认目标服务器是否允许后续的实际请求。它是浏览器实现 CORS 安全策略的重要机制,核心逻辑如下:
🔍 为什么需要预检请求?
浏览器对 "非简单请求"(可能对服务器数据产生较大影响的请求)会格外谨慎。例如:
- 方法:PUT、DELETE、CONNECT 等非 GET/POST 方法
- 头部 :包含自定义头部(如
X-Custom-Header
)或超出简单头部(如Content-Type
非application/x-www-form-urlencoded
/multipart/form-data
/text/plain
) - 内容 :请求体包含复杂数据(如 JSON 格式且
Content-Type
为application/json
)
预检请求通过OPTIONS 方法提前询问服务器:"我要发送这样的请求,你允许吗?",避免直接发送可能被拒绝的请求,减少安全风险。
📡 预检请求的流程
-
浏览器发起预检 :
发送
OPTIONS
请求,包含以下关键头:Origin
:当前网页域名(必填)Access-Control-Request-Method
:实际请求的方法(如PUT
)Access-Control-Request-Headers
:实际请求将携带的自定义头部(如X-Token
)
-
服务器响应验证 :
服务器需返回
200 OK
,并包含以下关键头(缺一不可):Access-Control-Allow-Origin
:允许的源(如https://example.com
)Access-Control-Allow-Methods
:允许的方法(如GET, POST, PUT
)Access-Control-Allow-Headers
:允许的头部(如X-Token, Content-Type
)Access-Control-Max-Age
:预检结果的缓存时间(秒,避免重复预检)
-
发送实际请求 :
若服务器验证通过,浏览器发送实际请求;否则终止请求并报错(如
No 'Access-Control-Allow-Origin'
)。
🚦 简单请求 vs 非简单请求
类型 | 条件(同时满足) | 是否触发预检 |
---|---|---|
简单请求 | 方法为 GET/POST; Content-Type 为简单类型; 无自定义头部 | 否 |
非简单请求 | 不满足上述任一条件 | 是 |
示例:
- 简单请求:
POST /api/data
+Content-Type: application/x-www-form-urlencoded
(不预检) - 非简单请求:
PUT /api/data
+Content-Type: application/json
+X-Token: xxx
(触发预检)
⚠️ 常见问题
- 服务器未配置 CORS :预检响应缺少必要头部,导致请求失败。
✅ 解决方案:服务器需正确返回Access-Control-*
系列头。 - 预检缓存 :
Access-Control-Max-Age
默认 0(每次请求都预检),建议设置合理值(如 86400 秒 = 1 天)。 - 浏览器行为:预检请求由浏览器自动发起,前端代码无需手动处理,但需确保服务器配置正确。
🌰 一个预检请求的例子
场景 :前端向https://api.example.com
发送PUT
请求,携带X-Custom-Header
。
-
预检请求(OPTIONS) :
httpOPTIONS /resource HTTP/1.1 Origin: https://web.example.com Access-Control-Request-Method: PUT Access-Control-Request-Headers: X-Custom-Header
-
服务器响应:
httpHTTP/1.1 200 OK Access-Control-Allow-Origin: https://web.example.com Access-Control-Allow-Methods: GET, POST, PUT Access-Control-Allow-Headers: X-Custom-Header, Content-Type Access-Control-Max-Age: 86400
-
实际请求(PUT) :
httpPUT /resource HTTP/1.1 Origin: https://web.example.com X-Custom-Header: value Content-Type: application/json
总结
预检请求是 CORS 机制的 "安全门卫",通过 OPTIONS 方法提前验证跨域请求的合法性。理解它的触发条件和服务器配置要求,能有效解决跨域问题,提升前端与后端的协作效率。