什么时候需要配 CORS、怎么配、配在哪里
| 场景 | 需要 CORS? |
|---|---|
用户点 <a href> 下载 | 不需要 |
window.open(presignedUrl) | 不需要 |
<img> / <video> 加载 | 不需要 |
| 后端/服务器请求 S3 | 不需要 |
| 手机原生 APP 请求 | 不需要 |
前端 JS fetch() 跨域读文件 | 需要 |
| 前端 JS 下载文件显示进度条 | 需要 |
Canvas toBlob() 跨域图片 | 需要 |
| Web 字体从 CDN 加载 | 需要 |
| 方案 1: CF Response Headers Policy | 方案 2: S3 Bucket CORS | |
|---|---|---|
| CORS 头来源 | CloudFront 强制插入 | S3 返回 |
| 需要改 S3? | 不需要 | 需要 |
| 需要转发 Origin? | 不需要 | 需要(ORP 配 Origin header) |
| 复杂度 | 低 | 中 |
| 适用 | 通用,推荐 | 需要精细控制哪些 origin |
在 CloudFront 层强制给所有响应加 CORS 头,无需修改 S3 桶配置。
aws cloudfront create-response-headers-policy \
--response-headers-policy-config '{
"Name": "CORS-AllowAll",
"Comment": "Allow all origins for GET/HEAD",
"CorsConfig": {
"AccessControlAllowOrigins": {"Quantity": 1, "Items": ["*"]},
"AccessControlAllowMethods": {"Quantity": 2, "Items": ["GET", "HEAD"]},
"AccessControlAllowHeaders": {"Quantity": 1, "Items": ["*"]},
"AccessControlExposeHeaders": {"Quantity": 0, "Items": []},
"AccessControlAllowCredentials": false,
"AccessControlMaxAgeSec": 86400,
"OriginOverride": true
}
}'
Console → Distribution → Behavior → Edit → Response headers policy → 选择 CORS-AllowAll
curl -I -X OPTIONS \ -H "Origin: https://your-app.com" \ -H "Access-Control-Request-Method: GET" \ https://d1234.cloudfront.net/file.jpg # access-control-allow-origin: * # access-control-allow-methods: GET, HEAD
让 S3 自己返回 CORS 头。需要 CloudFront 转发 Origin header。
aws s3api put-bucket-cors --bucket your-bucket --cors-configuration '{
"CORSRules": [{
"AllowedOrigins": ["https://your-app.com"],
"AllowedMethods": ["GET", "HEAD"],
"AllowedHeaders": ["*"],
"ExposeHeaders": ["Content-Length", "Content-Type"],
"MaxAgeSeconds": 3600
}]
}'
# managed ORP: CORS-S3Origin (88a5eaf4-2fd4-4709-b370-b4c650ea3fcf)
# 或自定义 ORP:
aws cloudfront create-origin-request-policy \
--origin-request-policy-config '{
"Name": "ForwardOriginAndQS",
"HeadersConfig": {"HeaderBehavior": "whitelist", "Headers": {"Quantity": 1, "Items": ["Origin"]}},
"CookiesConfig": {"CookieBehavior": "none"},
"QueryStringsConfig": {"QueryStringBehavior": "all"}
}'
缓存开启时必须把 Origin 加入 Cache Key,否则无 CORS 头的缓存会影响后续请求。
* 有安全风险吗?When you need CORS, how to configure it, and where
| Scenario | CORS needed? |
|---|---|
User clicks <a href> to download | No |
window.open(presignedUrl) | No |
<img> / <video> tag loading | No |
| Backend / server-side requests | No |
| Native mobile APP | No |
Frontend JS fetch() cross-origin | Yes |
| JS download with progress bar | Yes |
Canvas toBlob() on cross-origin image | Yes |
| Web fonts from CDN | Yes |
| Option 1: CF Response Headers Policy | Option 2: S3 Bucket CORS | |
|---|---|---|
| CORS header source | CloudFront injects | S3 returns |
| Modify S3? | No | Yes |
| Forward Origin header? | No | Yes (via ORP) |
| Complexity | Low | Medium |
| Best for | General use, recommended | Fine-grained origin control |
CloudFront injects CORS headers into every response. No S3 changes required.
aws cloudfront create-response-headers-policy \
--response-headers-policy-config '{
"Name": "CORS-AllowAll",
"Comment": "Allow all origins for GET/HEAD",
"CorsConfig": {
"AccessControlAllowOrigins": {"Quantity": 1, "Items": ["*"]},
"AccessControlAllowMethods": {"Quantity": 2, "Items": ["GET", "HEAD"]},
"AccessControlAllowHeaders": {"Quantity": 1, "Items": ["*"]},
"AccessControlExposeHeaders": {"Quantity": 0, "Items": []},
"AccessControlAllowCredentials": false,
"AccessControlMaxAgeSec": 86400,
"OriginOverride": true
}
}'
Console → Distribution → Behavior → Edit → Response headers policy → Select CORS-AllowAll
curl -I -X OPTIONS \ -H "Origin: https://your-app.com" \ -H "Access-Control-Request-Method: GET" \ https://d1234.cloudfront.net/file.jpg # access-control-allow-origin: * # access-control-allow-methods: GET, HEAD
S3 returns CORS headers natively. Requires CloudFront to forward the Origin header.
aws s3api put-bucket-cors --bucket your-bucket --cors-configuration '{
"CORSRules": [{
"AllowedOrigins": ["https://your-app.com"],
"AllowedMethods": ["GET", "HEAD"],
"AllowedHeaders": ["*"],
"ExposeHeaders": ["Content-Length", "Content-Type"],
"MaxAgeSeconds": 3600
}]
}'
# Managed ORP: CORS-S3Origin (88a5eaf4-2fd4-4709-b370-b4c650ea3fcf)
# Or custom ORP:
aws cloudfront create-origin-request-policy \
--origin-request-policy-config '{
"Name": "ForwardOriginAndQS",
"HeadersConfig": {"HeaderBehavior": "whitelist", "Headers": {"Quantity": 1, "Items": ["Origin"]}},
"CookiesConfig": {"CookieBehavior": "none"},
"QueryStringsConfig": {"QueryStringBehavior": "all"}
}'
With caching enabled, Origin must be in the Cache Key. Otherwise a cached response without CORS headers will be served to subsequent requests that include Origin.
* a security risk?