CloudFront未遵循S3内相对路径的问题排查与解决
问题原因
- 资源路径使用根相对路径:HTML中引用资源的路径以
/开头(如/assets/index.css),这种路径会被浏览器解析为基于当前域名的根目录发起请求,而非页面所在的子目录/site-1/。 - CloudFront默认路径转发逻辑:CloudFront会将请求路径原样转发给S3,当请求
https://me.cloudfront.com/assets/index.css时,S3会去桶的根目录查找assets文件夹,而非site-1子目录下的对应资源。
解决配置方案
方案一:修改HTML资源引用路径(最简方案)
将HTML中的根相对路径改为相对路径,去掉开头的/:
<link rel="stylesheet" href="assets/index.css" /> <script src="assets/main.js"></script>
浏览器会基于当前页面的URL路径(如/site-1/)自动拼接资源路径,最终请求/site-1/assets/index.css,符合预期。
方案二:使用CloudFront函数重写请求路径(无需修改HTML)
如果无法修改HTML代码,可通过CloudFront的路径重写功能,将根目录下的/assets/*请求转发到对应子目录:
步骤1:创建CloudFront函数
编写Viewer Request类型的函数,根据请求的Referer判断来源站点,重写路径:
function handler(event) { const request = event.request; const uri = request.uri; const referer = request.headers.referer?.value; if (uri.startsWith('/assets/') && referer) { if (referer.includes('/site-1/')) { request.uri = '/site-1' + uri; } else if (referer.includes('/site-2/')) { request.uri = '/site-2' + uri; } } return request; }
步骤2:关联函数到CloudFront分配
将上述函数发布后,关联到CloudFront分配的Viewer Request事件上,确保所有进入CloudFront的请求都会被该函数处理。
方案三:配置CloudFront行为与Origin Path(适合多站点独立路由)
为每个子站点单独配置CloudFront行为,指定对应的S3子目录作为源路径:
- 创建CloudFront行为:
- 针对路径模式
/site-1/*,创建新行为,将源的Origin Path设置为/site-1,这样CloudFront会将/site-1/*的请求转发到S3桶的site-1子目录。 - 同理,为
/site-2/*创建行为,Origin Path设为/site-2。
- 针对路径模式
- 适配资源路径:如果希望用户通过
https://me.cloudfront.com/site-1/访问站点,可将HTML资源路径改为/site-1/assets/index.css,或保持相对路径(方案一的写法)。
内容的提问来源于stack exchange,提问作者FRMR
相关产品推荐
相关产品推荐

