You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

禁用S3公共访问后,CloudFront访问NextJS静态站子页面异常

解决CloudFront+S3托管NextJS静态站点刷新子页面AccessDenied问题

问题原因

刷新子页面(如https://example.com/another-page)时,CloudFront会直接向S3请求another-page对象,但NextJS静态导出的子页面实际存储为S3中的another-page/index.html。S3找不到对应对象,就返回AccessDenied错误。而页面跳转正常是因为前端路由是客户端侧跳转,未触发真实的源站请求。

解决方案:请求路径重写(推荐用CloudFront函数)

通过CloudFront函数修改请求路径,将子页面请求自动映射到对应的index.html文件,步骤如下:

  • 登录AWS控制台,进入CloudFront服务,创建新的CloudFront函数
  • 将以下代码粘贴到函数编辑器中:
function handler(event) {
    const request = event.request;
    const uri = request.uri;

    // 处理非文件路径(无后缀)且不以/结尾的请求
    if (!uri.includes('.') && !uri.endsWith('/')) {
        request.uri = `${uri}/index.html`;
    }
    // 处理以/结尾的请求
    else if (uri.endsWith('/')) {
        request.uri = `${uri}index.html`;
    }

    return request;
}
  • 发布该函数,然后将其关联到你的CloudFront分发的Viewer Request事件(作用于所有缓存行为)

备选方案:自定义错误响应(地址栏会变更)

如果不想用函数,可配置CloudFront自定义错误响应,将403错误重定向到站点根目录的index.html,由NextJS前端路由接管:

  • 进入CloudFront分发的错误响应设置
  • 添加自定义错误响应:
    • HTTP错误代码:403 Forbidden
    • 自定义响应代码:200 OK
    • 自定义响应页面路径:/index.html
  • 保存配置后,刷新子页面时会返回根页面,再由前端路由渲染对应内容,但地址栏会保持为根路径,体验不如路径重写方案。

内容的提问来源于stack exchange,提问作者netsrikc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 11:00:42