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
页面刷出来是白屏,F12 一打开,控制台满屏红字:Access to image at 'https://xxx.s3.amazonaws.com' has been blocked by CORS policy。资源明明存在、单独开一个标签页还能正常加载,偏偏嵌进页面就不行——这就是跨域资源共享(CORS)没配对导致的经典翻车现场。这里只讲 S3 桶这一侧的修法:从最小配置到生产白名单,配完再把高频报错对一遍。如果你正被前端图片加载失败、或上传时的预检请求OPTIONS 卡住,可以跟着下面动手。
看懂浏览器拦截跨域的原理
浏览器规定:A 域名的页面要读 B 域名的资源,响应里必须带Access-Control-Allow-Origin头,且取值匹配 A 的源,才把数据交给前端代码。S3 桶默认不下发这个头,所以跨域一失败就得去桶上主动配规则。类比小区门禁:访客刷卡能进大楼,但没开他权限内楼层的门,电梯到不了那一层,数据也一样被拦在走廊里。一个判断口诀:直接开 URL 能加载、页面里加载失败,问题就在桶的跨域头上。
拆三类最常撞上的场景
- 前端页面直接引用 S3 里的图片:页面域名和桶域名一不同,图片就裂开。桶必须声明接受哪个来源,把页面域名(含协议和端口)原样写进白名单即可。
- 用 CloudFront 在 S3 前面分发静态资源:浏览器看到的来源变成了 CDN 域名,规则里没写它,用户换个入口访问照样报跨域错。
- 前端 JS 直接向桶 PUT 上传文件:浏览器会先发一次 OPTIONS 预检请求,方法列表里少一个 PUT 或 OPTIONS,上传在第一步就失败;别忘了同步确认桶策略允许匿名写。
动手配置跨域规则
规则是一段 JSON,在 桶 → 权限 → 跨域资源共享 面板粘贴保存,命令行等价命令如下:
aws s3api put-bucket-cors \ --bucket your-bucket-name \ --cors-configuration file://cors.jsonfile:// 前缀不能漏,否则报参数错。
最小可用配置:先把页面跑起来
开发验证阶段用它,只放行自己的域名和 GET。
{ "CORSRules": [ { "AllowedHeaders": ["*"], "AllowedMethods": ["GET"], "AllowedOrigins": ["https://your-domain.com"] } ] }AllowedOrigins 要带协议头,裸域名会被静默忽略。
生产白名单配置:方法收紧为只读
上线前收紧:方法只留只读,显式带上 OPTIONS。
{ "CORSRules": [ { "AllowedHeaders": ["Content-Type", "Authorization"], "AllowedMethods": ["GET", "HEAD", "OPTIONS"], "AllowedOrigins": ["https://your-domain.com"], "ExposeHeaders": ["ETag"], "MaxAge": 3600 } ] }MaxAge 是预检缓存秒数,填 0 会让复杂请求多跑一次 OPTIONS。
进阶:放开前端直传
要浏览器直传文件时,追加一条放行写方法的规则。
{ "CORSRules": [ { "AllowedHeaders": ["Content-Type", "x-amz-acl"], "AllowedMethods": ["PUT", "POST"], "AllowedOrigins": ["https://your-domain.com"], // "MaxAge": 3600 } ] }规则加进 CORSRules 数组,保存前删掉注释行。
按报错现象排错
遇到报错先别乱猜,按现象对号入座,多数问题一次粘贴或一条命令就能修好。
| 现象 | 最可能原因 | 一步修复 |
|---|---|---|
| No 'Access-Control-Allow-Origin' header | 桶上没配 CORS 规则 | 按最小可用配置贴一条规则 |
| 直接开 URL 正常,页面里报 403 | 请求来源没在白名单里 | 把实际来源域名(含端口)加进 AllowedOrigins |
| PUT 直传失败,提示预检被拒 | OPTIONS/PUT 不在方法列表 | 给 AllowedMethods 补上 OPTIONS 和 PUT |
| 配置正确但页面仍报错 | 浏览器缓存了旧预检结果 | Ctrl+Shift+R 强刷,或等 MaxAge 过期 |
| 挂 CloudFront 后新域名报错 | 来源变成了 CDN 域名 | 规则里把 CDN 域名也加进白名单 |
如果两行都试完还不行,九成是规则没落在正确的桶上——多桶架构里很容易改错地方,保存后回控制台把 CORS 面板再确认一遍。遇到 403 也别急着怀疑 IAM 权限,先排除跨域头的问题,顺序反了会绕远路。静态网站托管场景下桶策略和 CORS 是两套东西,可参考 static-website-basic.json 对比检查。
下一步建议:先贴最小配置把链路跑通,再逐步收紧成生产白名单。桶的基础操作回顾可以看 S3 入门笔记。改完规则记得回页面强刷验证一次,别只信控制台里的配置。
【免费下载链接】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),仅供参考