本文目录导读:

关于跨域CORS(跨源资源共享)配置中“允许来源”(Access-Control-Allow-Origin)的设置,这是解决浏览器同源策略限制的核心,以下是详细的配置指南和注意事项:
基本配置方式
允许单个特定来源
# Nginx 示例 add_header 'Access-Control-Allow-Origin' 'https://www.example.com';
# Apache 示例 Header set Access-Control-Allow-Origin "https://www.example.com"
// Node.js (Express)
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', 'https://www.example.com');
next();
});
允许所有来源(生产环境慎用)
add_header 'Access-Control-Allow-Origin' '*';
动态配置允许来源
根据请求来源动态判断
// Node.js 示例 - 白名单模式
const allowedOrigins = [
'https://www.example.com',
'https://api.example.com',
'https://admin.example.com'
];
app.use((req, res, next) => {
const origin = req.headers.origin;
if (allowedOrigins.includes(origin)) {
res.header('Access-Control-Allow-Origin', origin);
}
next();
});
Nginx 动态配置
# 使用 map 指令动态判断
map $http_origin $allowed_origin {
default "";
"~^https?://(www|api|admin)\.example\.com$" $http_origin;
"~^https?://localhost:3000$" $http_origin;
}
server {
location / {
add_header 'Access-Control-Allow-Origin' $allowed_origin;
# 其他CORS头...
}
}
完整CORS配置示例
# Nginx 完整配置
location /api/ {
# 动态来源控制
set $cors_origin "";
if ($http_origin ~* "^https?://(www|api)\.example\.com$") {
set $cors_origin $http_origin;
}
if ($http_origin ~* "^https?://localhost:3000$") {
set $cors_origin $http_origin;
}
add_header 'Access-Control-Allow-Origin' $cors_origin;
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Max-Age' 86400;
# 处理预检请求
if ($request_method = 'OPTIONS') {
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
}
重要注意事项
安全限制
- 不允许通配符与凭证同时使用:如果设置了
Access-Control-Allow-Credentials: true,则不能使用 ,必须指定具体来源 - 确切匹配:浏览器要求精确匹配,不能使用模式匹配(如
*.example.com) - 协议必须一致:
http://example.com和https://example.com被视为不同来源
常见错误配置
// ❌ 错误:不能同时使用 * 和 credentials
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Credentials', 'true'); // 会报错
// ✅ 正确
res.header('Access-Control-Allow-Origin', 'https://www.example.com');
res.header('Access-Control-Allow-Credentials', 'true');
预检请求处理
对于复杂请求(非简单请求),浏览器会先发送 OPTIONS 预检请求,必须正确处理:
if ($request_method = 'OPTIONS') {
return 204; # 或 200
}
不同场景配置建议
| 场景 | 推荐配置 | 说明 |
|---|---|---|
| 开发环境 | 或 http://localhost:3000 |
便于调试 |
| 公开API | (无凭证) + 其他安全措施 | 适用于公共资源 |
| 带有认证的API | 具体来源列表 + credentials:true | 需要严格白名单 |
| 子域名 | 逐个列出或在应用层处理 | Nginx不能使用通配符 |
调试技巧
- 查看浏览器控制台:具体错误信息会显示被拒绝的来源
- 使用 curl 测试:
curl -H "Origin: https://www.example.com" -I https://api.example.com
- 查看响应头:检查
Access-Control-Allow-Origin是否返回预期值
框架配置示例
# Flask from flask_cors import CORS app = Flask(__name__) CORS(app, origins=["https://www.example.com", "https://api.example.com"])
// Spring Boot
@CrossOrigin(origins = {"https://www.example.com", "https://api.example.com"})
@RestController
public class ApiController { ... }
正确配置CORS允许来源是保障Web安全与功能正常的关键,建议根据实际业务需求选择具体的白名单策略。