跨源资源共享(Cross-Origin Resource Sharing, CORS)是现代 Web 开发中处理跨域请求的核心机制。理解简单请求(Simple Request)与预检请求(Preflight Request)的区别,是避免常见跨域问题的重要前提。本文将深入解析这两种请求类型的工作原理和配置要点。


一、CORS 基础与同源策略

为什么需要 CORS?

  • 同源策略限制:浏览器默认阻止跨域 AJAX 请求(协议/域名/端口任一不同)

  • 安全与功能的平衡:CORS 通过标准化头部实现安全的跨域通信


二、简单请求(Simple Request)

触发条件(同时满足):

  1. HTTP 方法:GET / HEAD / POST

  2. 自定义头部:仅允许以下安全头部:

    • Accept

    • Accept-Language

    • Content-Language

    • Content-Type(仅限特定值)

  3. 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

完整请求流程:

  1. OPTIONS 预检请求

 
OPTIONS /data HTTP/1.1
Origin: https://example.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header
  1. 服务器响应预检

 
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
  1. 实际请求发送

 
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

⚠️ 使用凭证时禁止使用通配符(*)


六、常见问题排查

  1. 预检失败原因

    • 未正确处理 OPTIONS 方法

    • 响应头缺少 Allow-Methods/Allow-Headers

    • 服务端未返回 2xx 状态码

  2. 调试技巧

    • 使用浏览器开发者工具查看 Network 面板

    • 检查请求头中的 Origin 和响应头中的 Access-Control-* 系列

    • 验证预检响应是否包含正确的方法和头部


七、安全注意事项

  1. 避免过度开放

    • 严格限制 Access-Control-Allow-Origin 域名

    • 按需配置允许的方法和头部

  2. 敏感操作保护

    • 对修改型操作(PUT/DELETE)强制使用预检

    • 结合 CSRF 令牌等额外保护措施


结语

理解简单请求与预检请求的差异,能帮助开发者:

  • 合理设计 API 接口

  • 正确配置 CORS 策略

  • 快速诊断跨域问题

  • 平衡安全性与功能性

通过本文的机制解析和配置示例,开发者可以更从容地应对现代 Web 应用中的跨域挑战。建议结合具体框架(如 Express CORS 中间件)进行实践,同时定期审查 CORS 配置的安全性。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
意见
建议
发表
评论
返回
顶部