NextJS静态站部署S3/CloudFront:省略.html及去除末尾斜杠问题
问题1:S3省略.html后缀访问403的解决办法
方案1:S3静态网站托管+CloudFront(推荐)
- 打开S3桶的静态网站托管功能,设置索引文档为
index.html,错误文档按需配置(比如404.html)。 - 此时S3会自动将无后缀的路径映射到对应
.html文件(比如/user/v1/login会匹配/user/v1/login.html),但S3网站端点默认是HTTP协议,所以搭配CloudFront做HTTPS转发——把CloudFront的源设置为S3的网站端点(不是S3的REST API地址),既能实现无后缀访问,又能用上HTTPS。
方案2:S3重定向规则(无需CloudFront,但会产生跳转)
- 在S3桶的「权限」→「静态网站托管」→「重定向规则」中添加以下XML规则:
<RoutingRules> <RoutingRule> <Condition> <KeyPrefixEquals/> <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals> </Condition> <Redirect> <HostName>my-website.s3.ap-southeast-1.amazonaws.com</HostName> <ReplaceKeyPrefixWith>$1.html</ReplaceKeyPrefixWith> <HttpRedirectCode>301</HttpRedirectCode> </Redirect> </RoutingRule> </RoutingRules>
这个规则会把404的请求自动补上.html后缀并重定向,但浏览器地址栏会显示带后缀的URL,体验不如方案1。
问题2:CloudFront自动追加末尾斜杠的解决办法
用CloudFront搭配S3网站端点时,S3默认会把无斜杠的路径301跳转到带斜杠的版本,哪怕带查询参数也一样。要阻止这个行为,得用CloudFront的Lambda@Edge修改请求逻辑:
步骤1:创建Origin Request Lambda函数
- 在AWS Lambda控制台(必须选
us-east-1区域,否则无法关联CloudFront)创建Node.js函数,代码如下:
exports.handler = (event, context, callback) => { const request = event.Records[0].cf.request; const uri = request.uri; // 路径不以斜杠结尾、且没有文件后缀的,保持原URI不变 if (!uri.endsWith('/') && !uri.includes('.')) { request.uri = uri; } callback(null, request); };
这个函数会拦截发往S3的请求,避免S3触发自动加斜杠的跳转。
步骤2:关联Lambda到CloudFront的Origin Request事件
- 发布Lambda函数的新版本,然后在CloudFront控制台的对应分发中添加行为,将这个Lambda函数关联到Origin Request事件类型,路径匹配规则设为
/*以覆盖所有请求。
辅助调整:优化CloudFront缓存设置
- 确保CloudFront缓存行为里的「转发查询字符串」设置为「全部」,避免因查询字符串导致路径解析异常。
- 另外,S3静态网站托管中不要开启“重定向所有请求到另一个主机名”,仅启用静态网站托管即可。
内容的提问来源于stack exchange,提问作者jianlong
相关产品推荐
相关产品推荐

