CORS协议详解
CORS(Cross-Origin Resource Sharing)是W3C标准,通过HTTP头部实现跨域授权。
CORS核心响应头
Access-Control-Allow-Origin
指定允许访问的源:
http
Access-Control-Allow-Origin: * // 允许所有源
Access-Control-Allow-Origin: http://localhost:3000 // 允许特定源
Access-Control-Allow-Methods
允许的HTTP方法:
http
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers
允许的请求头:
JavaScript
Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With
Access-Control-Allow-Credentials
是否允许携带Cookie:
http
Access-Control-Allow-Credentials: true
携带凭证时,
Access-Control-Allow-Origin不能为*,必须指定具体源。
Access-Control-Max-Age
预检请求缓存时间(秒):
text
Access-Control-Max-Age: 3600
简单请求与预检请求
简单请求条件
同时满足以下条件:
| 条件 | 要求 |
|---|---|
| 请求方法 | GET、POST、HEAD |
| 请求头 | Accept、Accept-Language、Content-Language、Content-Type(仅限text/plain、multipart/form-data、application/x-www-form-urlencoded) |
| 无自定义头 | 不能有自定义请求头 |
简单请求流程
text
浏览器 服务器
| |
|------- GET/POST ------------->|
| |
|<-- Response + CORS Headers ---|
| |
示例:
text
GET /api/users HTTP/1.1
Host: localhost:8080
Origin: http://localhost:3000
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://localhost:3000
Content-Type: application/json
[{"id":1,"name":"张三"}]
预检请求(Preflight)
不满足简单请求条件时,浏览器先发送OPTIONS请求:
text
浏览器 服务器
| |
|------- OPTIONS -------------->| 预检请求
|<-- CORS Headers --------------| 预检响应
| |
|------- 实际请求 ------------->|
|<-- Response + CORS Headers ---|
| |
预检请求示例:
text
OPTIONS /api/users HTTP/1.1
Host: localhost:8080
Origin: http://localhost:3000
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://localhost:3000
Access-Control-Allow-Methods: POST, GET, PUT, DELETE
Access-Control-Allow-Headers: Content-Type
Access-Control-Max-Age: 3600
常见请求场景对比
| 场景 | 请求类型 | 是否预检 |
|---|---|---|
| 普通表单提交 | POST | 否 |
| JSON数据提交 | POST | 是(Content-Type: application/json) |
| 自定义请求头 | GET/POST | 是 |
| PUT/DELETE请求 | PUT/DELETE | 是 |
携带凭证的CORS请求
前端配置:
text
// 使用fetch
fetch('http://localhost:8080/api/users', {
credentials: 'include' // 携带Cookie
});
// 使用axios
axios.get('http://localhost:8080/api/users', {
withCredentials: true
});
后端响应:
text
Access-Control-Allow-Origin: http://localhost:3000 // 必须指定具体源
Access-Control-Allow-Credentials: true
要点总结
- CORS通过HTTP响应头实现跨域授权
- 简单请求直接发送,预检请求先发OPTIONS
- 携带凭证时Origin不能为通配符
- Access-Control-Max-Age可缓存预检结果
- 理解简单请求与预检请求的区别是解决跨域的关键
📝 发现内容有误?点击此处直接编辑