S3 CORS 配置模板速查:跨域请求报错快速定位与修复
【免费下载链接】aws-devops-zero-to-heroAWS zero to hero repo for devops engineers to learn AWS in 30 Days. This repo includes projects, presentations, interview questions and real time examples.项目地址: https://gitcode.com/GitHub_Trending/aw/aws-devops-zero-to-hero
在 AWS 30 天 DevOps 学习项目(aws-devops-zero-to-hero)里,前端页面请求 S3 上的静态资源却被浏览器判定跨域拦截时,问题几乎都出在 S3 CORS 配置上;本文给出一套可直接粘贴的 JSON 模板、落地命令和一份排查清单。
锚点是一条真实报错:No 'Access-Control-Allow-Origin' header is present on the requested resource。看到这个提示先别查网络,往下看。
先定位你卡在哪一步
动手之前先判断报错类型,30 秒对号入座:
| 症状 / 报错 | 可能原因 | 跳到 |
|---|---|---|
| 控制台报 CORS 错误,图片白屏 | 桶上没配 CORS 规则,或请求方 Origin 不在白名单 | 一份能直接粘贴的 CORS 规则 |
| OPTIONS 预检返回 403,PUT 上传被拦 | AllowedMethods 没包含写操作,预检缓存没设置 | 按你的场景选模板 |
| curl 正常但浏览器仍报错 | 配置写错桶,或 CloudFront 层吞掉了 CORS 响应头 | 配置生效了但浏览器仍在报错? |
一份能直接粘贴的 CORS 规则
最常见的错误是先甩一个*上去。生产环境从最小权限起步,最省事的办法是往桶上挂一份 S3 CORS JSON 模板:
{ "CORSRules": [ { "AllowedOrigins": ["https://assets.example.com"], "AllowedMethods": ["GET", "HEAD"], "AllowedHeaders": ["*"], "MaxAge": 86400 } ] }AllowedOrigins:写"协议 + 域名"全量,https://assets.example.com和assets.example.com是两个不同的 Origin。先别急着加*——请求一旦携带凭据,通配源会被浏览器直接拒掉。AllowedMethods与AllowedHeaders:Preflight(OPTIONS)预检就是对照这两项放行或拦截。前端只读资源时 GET/HEAD 足够;请求头里带 Authorization 就单独列出来。MaxAge:预检结果允许缓存的秒数。设太短,每个请求都要多跑一次 OPTIONS 往返;生产静态资源给到 86400,一天最多一次预检。ExposeHeaders:浏览器默认只向 JS 暴露一组白名单响应头,前端要读白名单之外的头(比如自定义的 x-amz- 头)才需要在这里追加,否则留空即可。
按你的场景选模板
S3 跨域请求 preflight 其实只查这几个字段,所以模板按"前端做什么"来分,而不是按"多严格"来分。
生产环境静态资源只读分发
桶只放图片、JS、CSS,站点域名固定,这是最典型的读场景。
{ "CORSRules": [ { "AllowedOrigins": ["https://www.example.com"], "AllowedMethods": ["GET", "HEAD"], "AllowedHeaders": ["*"], "MaxAge": 86400 } ] }⚠️ 规则只放行列出的 Origin,日后新增域名忘了追加,跨域报错就会换个姿势再出现一次。
管理后台上传与删除
后台页面做预签名直传 PUT、清理过期文件 DELETE,需要读写权限,且要显式声明请求头。
{ "CORSRules": [ { "AllowedOrigins": ["https://admin.example.com"], "AllowedMethods": ["PUT", "POST", "DELETE"], "AllowedHeaders": ["Authorization", "Content-Type"], "ExposeHeaders": ["ETag"], "MaxAge": 3000 } ] }⚠️ DELETE 是破坏性操作,来源只写管理后台域名,别和公开的只读规则混在一条里。
本地开发调试
本地localhost端口经常变动,这里追求的是改起来快、不用反复审批。
{ "CORSRules": [ { "AllowedOrigins": ["http://localhost:3000", "http://localhost:5173"], "AllowedMethods": ["*"], "AllowedHeaders": ["*"], "MaxAge": 0 } ] }⚠️*只给开发桶用,带进生产桶等于把所有写操作暴露给任意站点。
控制台 or CLI,两种方式落地
控制台操作,4 步:
- 打开 S3 控制台,点进目标桶
- 切到"权限"选项卡
- 展开"跨域资源共享(CORS)"
- 粘贴上面的 JSON,保存
桶由命令行管理的场景,S3 CORS CLI 命令一行搞定:
aws s3api put-bucket-cors \ --bucket my-bucket \ --cors-configuration file://cors.json生产环境建议用 IaC 管理 CORS 配置:把 JSON 文件提交进代码库、和桶的定义放在一起,出了问题可追溯,环境重建时也能一键还原。
配置生效了但浏览器仍在报错?
报错还在时别乱调 CORS。S3 跨域 403 排查建议按"最可能 → 最不可能"的顺序逐项过:
- 强制刷新浏览器(Ctrl+Shift+R):预检结果被 MaxAge 缓存过,旧的一次 403 可能还压在缓存里。
- 确认配置写到了正确的桶:多账号、多环境的项目最容易配错桶,回浏览器看请求实际打到的域名,再去对应桶的"权限"页核对。
- 检查是否有其他 Bucket Policy 在覆盖:策略里对同一资源 deny 的条目会绕过 CORS 直接拦截请求,最小化策略形态可参考仓库里的 Bucket 策略示例。
- 如果 S3 前面挂了 CloudFront,CORS 响应头可能在 CDN 层丢失,需要在分发配置里同步补上响应头,CDN 层的细节可看 day-19 的 CloudFront 说明。
- 核对浏览器发出的 Origin 和配置里写的是否逐字一致:
http还是https、有没有端口,差一个字符都算不匹配。
上线前检查清单
- AllowedOrigins 只保留真实业务域名,没有任何
*残留 - AllowedMethods 与前端实际发出的 HTTP 方法一一对应,没有多开
- CORS JSON 文件已随桶的定义一起提交进代码库,改动可审查、可回滚
- 用 curl 发 OPTIONS 预检请求验证返回 200,且响应头里带 Access-Control-Allow-Origin
- 前面挂了 CloudFront 时,CDN 层的 CORS 响应头已同步配置
字段定义和边界行为的更多细节,以 AWS 官方 S3 用户指南的 CORS 章节为准;完整的学习路径和配套项目见仓库 README。下次遇到新的 Origin 需求,只需在 AllowedOrigins 数组里追加一项并重新 apply,无需推倒整条规则重来。
【免费下载链接】aws-devops-zero-to-heroAWS zero to hero repo for devops engineers to learn AWS in 30 Days. This repo includes projects, presentations, interview questions and real time examples.项目地址: https://gitcode.com/GitHub_Trending/aw/aws-devops-zero-to-hero
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考