透析 HTTP OPTIONS 预检请求
HTTP OPTIONS 预检请求是浏览器在发送某些跨域请求(CORS,跨源资源共享)之前自动发起的一种机制,其核心作用是确保目标服务器允许实际的跨域请求。它是现代浏览器实现CORS规范的关键安全措施,目的是保护服务器免受恶意跨域请求的攻击。
为什么需要预检请求?
在跨域场景下,浏览器默认遵循同源策略(Same-Origin Policy),禁止网页向不同源的服务器发送某些类型的请求(如带有自定义Header的请求或非简单请求方法)。为了安全地支持合法跨域请求,浏览器通过预检请求向服务器预先确认实际请求是否被允许,避免直接发送可能被服务器拒绝的敏感请求。
触发预检请求的条件
当跨域请求满足以下任一条件时,浏览器会先发送OPTIONS预检请求:
-
使用非简单请求方法:
-
如
PUT
、DELETE
、PATCH
等(简单方法仅限GET
、POST
、HEAD
)。
-
-
包含自定义请求头:
-
如
Authorization
、X-Custom-Header
等(简单Header仅限Accept
、Accept-Language
、Content-Language
、Content-Type
等)。
-
-
Content-Type 非简单类型:
-
如
application/json
(简单类型仅限text/plain
、multipart/form-data
、application/x-www-form-urlencoded
)。
-
预检请求的工作流程
-
浏览器发送OPTIONS请求:
-
包含以下关键头信息:
Origin: https://your-site.com // 请求来源 Access-Control-Request-Method: DELETE // 实际请求方法 Access-Control-Request-Headers: X-Custom-Header // 自定义请求头
-
-
服务器响应预检请求:
-
返回是否允许跨域请求的规则:
Access-Control-Allow-Origin: https://your-site.com // 允许的来源 Access-Control-Allow-Methods: GET, POST, DELETE // 允许的方法 Access-Control-Allow-Headers: X-Custom-Header // 允许的自定义头 Access-Control-Max-Age: 86400 // 预检结果缓存时间(秒)
-
-
浏览器决策:
-
如果服务器响应允许实际请求,浏览器继续发送真正的请求(如
DELETE
)。 -
如果服务器拒绝,浏览器抛出CORS错误,阻止实际请求。
-
预检请求的作用总结
作用 | 说明 |
---|---|
安全性验证 | 防止恶意网站直接发送敏感请求(如删除资源),需先通过服务器授权。 |
协商请求权限 | 明确服务器允许的跨域方法、Header、来源等,避免误操作。 |
减少无效请求 | 若预检失败,浏览器直接阻止后续请求,节省带宽和服务端资源。 |
缓存优化 | 通过 Access-Control-Max-Age 缓存预检结果,减少重复OPTIONS请求。 |
如何避免不必要的预检请求?
-
使用简单请求:
-
限制请求方法为
GET
/POST
/HEAD
,避免自定义Header,保持Content-Type
为简单类型。
-
-
合理配置CORS策略:
-
服务器端设置宽泛但安全的
Access-Control-Allow-*
头,覆盖常见需求。
-
-
利用缓存:
-
通过
Access-Control-Max-Age
延长预检结果的缓存时间(如设置86400秒=1天)。
-
示例:预检请求与响应
浏览器发送OPTIONS请求:
OPTIONS /api/data HTTP/1.1
Origin: https://frontend.com
Access-Control-Request-Method: DELETE
Access-Control-Request-Headers: X-Auth-Token
服务器响应:
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://frontend.com
Access-Control-Allow-Methods: GET, POST, DELETE
Access-Control-Allow-Headers: X-Auth-Token
Access-Control-Max-Age: 3600
关键点
-
预检请求是浏览器的自动行为,开发者无需手动处理。
-
服务器必须正确响应OPTIONS请求,否则跨域请求会被浏览器拦截。
-
预检机制是CORS安全的核心设计,确保跨域通信既灵活又安全。