CORS (跨源资源共享)
约 4 分钟阅读
最后更新: 2026-03-15
什么是 CORS (跨源资源共享)
CORS (Cross-Origin Resource Sharing) 是一种基于 HTTP 头的机制,用于安全地放宽浏览器的同源策略,实现不同源之间的资源共享。源由协议 (http/https)、主机名和端口号三个要素的组合定义。
同源策略是浏览器的安全机制,限制从一个源加载的脚本访问另一个源的资源。如果没有这个限制,恶意网站就可以通过用户的浏览器调用用户已登录的银行网站的 API。
然而,在现代 Web 应用中,前端和后端 API 运行在不同域名上是很常见的。CORS 通过服务器在 HTTP 响应头中明确声明「允许哪些源的访问」,安全地实现必要的跨源通信。
CORS 的工作机制
CORS 根据请求类型以两种方式工作。
简单请求 (Simple Request)
使用 GET、HEAD 或 POST (限于特定 Content-Type) 且不包含自定义头的请求被视为「简单请求」。浏览器直接发送请求,并检查响应中的 Access-Control-Allow-Origin 头。如果源被允许,则将响应传递给 JavaScript;否则阻止。
预检请求 (Preflight Request)
对于不满足简单请求条件的请求 (如 PUT、DELETE 或包含自定义头的请求),浏览器在实际请求之前使用 OPTIONS 方法发送「预检请求」。服务器通过以下头响应允许条件。
Access-Control-Allow-Origin:允许的源Access-Control-Allow-Methods:允许的 HTTP 方法Access-Control-Allow-Headers:允许的请求头Access-Control-Max-Age:预检结果的缓存时间 (秒)
如果预检响应满足允许条件,浏览器才发送实际请求。
携带凭据的请求
包含 Cookie 或认证头的跨源请求需要 Access-Control-Allow-Credentials: true。此时,Access-Control-Allow-Origin 不能使用通配符 (*),必须指定具体的源。
常见配置错误与安全风险
CORS 配置错误会使同源策略的保护失效,造成严重的安全风险。
- 随意使用
Access-Control-Allow-Origin: *:允许所有源意味着任何网站都可以访问 API。除公开 API 外不应使用。处理认证信息的 API 绝对不能使用 - 未经验证直接反映 Origin 头:将请求的 Origin 头值直接反映到
Access-Control-Allow-Origin中,实质上等同于通配符。应通过白名单验证 - 允许 null 源:允许
Access-Control-Allow-Origin: null会使沙箱化的 iframe 和本地文件可以访问,可能被攻击利用 - 过于宽松的子域匹配:使用
*.example.com这样的模式匹配时,如果攻击者能够接管子域,就可以利用 CORS
安全 CORS 配置的最佳实践
安全配置 CORS 的指南。
- 通过白名单管理允许的源:在环境变量或配置文件中维护允许源列表,与请求的 Origin 头进行精确匹配验证
- 仅允许最少必要的方法和头:在
Access-Control-Allow-Methods和Access-Control-Allow-Headers中只列出实际使用的内容 - 利用预检缓存:适当设置
Access-Control-Max-Age,减少预检请求频率,提升性能 - 谨慎处理携带凭据的请求:设置
Access-Control-Allow-Credentials: true时,严格限制允许的源 - 与 CSP 和安全头配合使用:将 CORS 与其他安全头结合,构建纵深防御
- 以 HTTPS 为前提:不在允许列表中包含 HTTP 源。防止通过中间人攻击伪造源
CORS 是浏览器端的控制,不适用于服务器间通信或命令行工具的请求。不要仅依赖 CORS,务必实现服务器端的认证和授权。
常见误解
- CORS 是保护服务器的安全功能
- CORS 是浏览器端的控制,不直接保护服务器。curl 或服务器间通信不受 CORS 限制。CORS 是保护浏览器用户的机制,与服务器端的认证和授权处于不同层面。
- 出现 CORS 错误用通配符 (*) 解决就好
- 通配符允许所有源的访问,安全风险很高。携带凭据的请求不能使用通配符。正确的做法是仅将必要的源添加到白名单中。