跨源资源共享(Cross-Origin Resource Sharing, CORS)是现代 Web 开发中处理跨域请求的核心机制。理解简单请求(Simple Request)与预检请求(Preflight Request)的区别,是避免常见跨域问题的重要前提。本文将深入解析这两种请求类型的工作原理和配置要点。
一、CORS 基础与同源策略
为什么需要 CORS?
-
同源策略限制:浏览器默认阻止跨域 AJAX 请求(协议/域名/端口任一不同)
-
安全与功能的平衡:CORS 通过标准化头部实现安全的跨域通信
二、简单请求(Simple Request)
触发条件(同时满足):
-
HTTP 方法:GET / HEAD / POST
-
自定义头部:仅允许以下安全头部:
-
Accept
-
Accept-Language
-
Content-Language
-
Content-Type(仅限特定值)
-
-
Content-Type:
-
text/plain
-
multipart/form-data
-
application/x-www-form-urlencoded
-
请求流程示例:
GET /data HTTP/1.1 Origin: https://example.com
HTTP/1.1 200 OK Access-Control-Allow-Origin: https://example.com
关键特点:
-
浏览器直接发送请求
-
服务器通过响应头控制访问权限
-
无预检环节,性能开销小
三、预检请求(Preflight Request)
触发场景:
-
非简单方法:PUT / DELETE / PATCH 等
-
自定义头部:X-Custom-Header 等非安全头部
-
特殊 Content-Type:如 application/json
完整请求流程:
-
OPTIONS 预检请求:
OPTIONS /data HTTP/1.1 Origin: https://example.com Access-Control-Request-Method: PUT Access-Control-Request-Headers: X-Custom-Header
-
服务器响应预检:
HTTP/1.1 204 No Content Access-Control-Allow-Origin: https://example.com Access-Control-Allow-Methods: PUT Access-Control-Allow-Headers: X-Custom-Header Access-Control-Max-Age: 86400
-
实际请求发送:
PUT /data HTTP/1.1 Origin: https://example.com X-Custom-Header: value
四、核心差异对比
特征 | 简单请求 | 预检请求 |
---|---|---|
请求方法 | GET/HEAD/POST | PUT/DELETE/PATCH 等 |
自定义头部 | 不允许 | 允许 |
Content-Type | 仅限简单类型 | 任意类型 |
实际请求次数 | 1次 | 2次(OPTIONS + 实际请求) |
性能影响 | 低 | 较高(需额外往返) |
五、服务器配置最佳实践
通用响应头设置:
Access-Control-Allow-Origin: https://trusted-domain.com Access-Control-Expose-Headers: X-Custom-Header
预检请求优化:
# 设置方法白名单 Access-Control-Allow-Methods: GET, POST, PUT # 允许特定头部 Access-Control-Allow-Headers: Content-Type, Authorization # 预检结果缓存(秒) Access-Control-Max-Age: 3600
凭证处理:
# 客户端
fetch(url, { credentials: 'include' })
# 服务端
Access-Control-Allow-Credentials: true
⚠️ 使用凭证时禁止使用通配符(*)
六、常见问题排查
-
预检失败原因:
-
未正确处理 OPTIONS 方法
-
响应头缺少 Allow-Methods/Allow-Headers
-
服务端未返回 2xx 状态码
-
-
调试技巧:
-
使用浏览器开发者工具查看 Network 面板
-
检查请求头中的
Origin
和响应头中的Access-Control-*
系列 -
验证预检响应是否包含正确的方法和头部
-
七、安全注意事项
-
避免过度开放:
-
严格限制
Access-Control-Allow-Origin
域名 -
按需配置允许的方法和头部
-
-
敏感操作保护:
-
对修改型操作(PUT/DELETE)强制使用预检
-
结合 CSRF 令牌等额外保护措施
-
结语
理解简单请求与预检请求的差异,能帮助开发者:
-
合理设计 API 接口
-
正确配置 CORS 策略
-
快速诊断跨域问题
-
平衡安全性与功能性
通过本文的机制解析和配置示例,开发者可以更从容地应对现代 Web 应用中的跨域挑战。建议结合具体框架(如 Express CORS 中间件)进行实践,同时定期审查 CORS 配置的安全性。
发表评论 取消回复