介绍
CORS(资源共享)是一种浏览器安全,用于控制来自一个源的网页如何请求来自不同源的资源。当https://app.example.com处的前端尝试从https://api.example.org获取数据时,浏览器默认强制执行同源策略。CORS提供了一种通过HTTP标头来放宽此策略的受控方法。本文介绍了完整的CORS流程、预检请求以及如何修复常见的阻止访问错误。
同源政策
起源由方案、主机和端口的组合定义:
| 网址 | 产地 |
|---|---|
| 占位符_0 | 占位符_1 |
| 占位符_0 | 同源 |
| 占位符_0 | 不同产地(不同方案) |
| 占位符_0 | 不同来源(不同主机) |
| 占位符_0 | 不同产地(不同口岸) |
默认情况下,同源策略会阻止读取跨源响应。这可以防止恶意站点窃取其他来源的数据。
简单请求与预检请求
CORS区分简单请求和触发预检的请求。
如果满足所有这些条件,请求就是简单:
- 方法:
GET、HEAD或POST - 内容类型:
application/x-www-form-urlencoded、multipart/form-data或text/plain - 没有自定义标头
对于简单请求,浏览器直接发送请求并检查响应中的CORS标头。
所有其他请求都会触发触发预检 — 实际上在发送的OPTIONS请求之前:
OPTIONS /api/data HTTP/1.1
Host: api.example.org
Origin: https://app.example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type, Authorization
服务器必须使用适当的 CORS 标头进行响应,浏览器才能继续。
核心 CORS 响应标头
服务器通过这些响应标头控制CORS行为:
| 标题 | 目的 |
|---|---|
| 占位允许符_0 | 指定哪些来源 |
| 占位允许符_0 | 上线的 HTTP 方法 |
| 占位允许符_0 | 上市的自定义请求标头 |
| 占位允许符_0 | 是否权限(cookie) |
| 占位符_0 | 预检结果可以缓存多长时间 |
| 占位符_0 | 哪些响应标头是可访问的 |
预检的 CORS 响应示例:
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 86400
通配符与特定起源
使用 Access-Control-Allow-Origin: * 允许任何来源,但有限制:
- 不能与
Access-Control-Allow-Credentials: true一起使用 - 只能用于公共、以太网API
对于请求请求,您必须指定目的的来源:
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Credentials: true
如果您需要多个允许的源,服务器必须在根据白名单验证请求源后动态回显请求源。
使用 CORS 处理 Cookie
要在跨源请求中包含cookie,客户端和服务器都必须选择加入:
客户端(JavaScript):
fetch('https://api.example.org/data', {
credentials: 'include', // sends cookies
});
** 服务器(响应标头):**
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Credentials: true
如果没有 credentials: 'include',cookie 永远不会跨源发送。
CORS 常见错误及解决方案
| 错误信息 | 可能的原因 | 修复 |
|---|---|---|
| 占位符_0 | 服务器上缺少 CORS 标头 | 添加 Access-Control-Allow-Origin |
| 占位符_0 | 来源不允许列表中 | 根据白名单验证来源 |
| 占位符_0 | 搭载笔记本的通配符 | 使用特定原点而不是* |
| 占位符_0 | 未上市的方法 | 将 PUT 到添加允许的方法 |
| 占位符_0 | 自定义标头不允许标头中 | 将标题添加到 Access-Control-Allow-Headers |
服务器配置示例
Express.js:
const cors = require('cors');
app.use(cors({
origin: 'https://app.example.com',
methods: ['GET', 'POST', 'PUT', 'DELETE'],
credentials: true,
}));
Nginx:
add_header Access-Control-Allow-Origin "https://app.example.com";
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
add_header Access-Control-Allow-Headers "Content-Type";
##结论
CORS 是一个关键的安全层,可以保护用户,同时实现合法的跨域交互。了解简单请求和预检请求之间的、了解要配置哪些标头区别以及正确处理后台是全栈开发人员的基本技能。通过正确配置服务器的 CORS 策略,您可以在不阻止有效跨域的情况下流量维护安全性。

