amazon-web-services - Next.js:托管在 AWS Cloudfront 上时,如何使链接与导出的站点一起使用?

标签 amazon-web-services amazon-s3 next.js amazon-cloudfront

我试图通过做一个 Static html export 来建立一个原型(prototype) Next.js 项目(即 next export ),然后将生成的输出复制到 AWS S3 并通过 Cloudfront 提供服务。
我在 /pages 中有以下两页目录:

  • index.tsx
  • Pricing.tsx

  • 然后,跟随 routing doco我加了一个 Link从索引页面到定价页面,如下所示:
    <Link href="/Pricing">
      <a>Pricing</a>
    </Link>
    
    这会导致链接看起来像 example.com/Pricing (当您将鼠标悬停在它上面并单击链接时,该页面确实会更改为定价页面,并且浏览器会在 URL 栏中显示“example.com/Pricing”)。
    问题是,该链接不是真实的 - 无法直接通过 url 栏添加书签或导航到它。
    问题似乎是当我做 next export 时, Next.js 生成一个 .html每个页面的文件,但路由器不使用这些 .html后缀。
    所以在使用本网站时,如果用户试图收藏example.com/Pricing ;稍后加载该书签将失败,因为 Cloudfront 将返回 404(因为 CF 只知道 .html 文件)。
    然后我尝试更改我的 Link看起来像:
    <Link href="/Pricing.html">
      <a>Pricing</a>
    </Link>
    
    这会导致路由器使用 example.com/Pricing.html这在 Cloudfront 上运行良好 - 但它实际上在本地开发期间导致 404(即使用 next dev )!
    我可以尝试的其他解决方法是重命名所有 .html文件并在我将它们上传到 S3 之前删除扩展名(并确保它们获得 content-type: text/html header ) - 或者引入一个 Cloudfront lambda,它在 .html 时即时进行重命名请求资源。我真的不想做 lambda 的事情,但上传前的重命名应该不会太难。
    但感觉就像我真的在这里上坡工作。我在基本层面上做错了吗? Next.js 链接应该如何与静态 html 导出一起使用?
    Next.js 版本:9.5.3-canary.23

    最佳答案

    如果您希望您的网址“干净”并且没有 .html 的替代答案最后。
    要使 Next.js 默认 URL 链接与 S3/Cloudfront 一起正常工作,您必须在 next.config.js 中配置“添加尾部斜杠”选项。 :

    module.exports = {
      trailingSlash: true,
    }
    
    根据 documentation

    export pages as index.html files and require trailing slashes, /about becomes /about/index.html and is routable via /about/. This was the default behavior prior to Next.js 9.


    所以现在您可以留下您的 Link定义为:
    <Link href="/Pricing">
      <a>Pricing</a>
    </Link>
    
    这会导致 Next.js 做两件事:
  • 使用网址 example.com/Pricing/ - 注意 /到底
  • 将每个页面生成为 index.html在它自己的目录中 - 例如/Pricing/index.html

  • 许多 HTML 服务器在其默认配置中会提供 index.html如果他们看到尾随 /,则从匹配目录中URL 中的字符。
    如果您将 S3 设置为网站和 ,S3 也会这样做。 IFF 您通过 website endpoint, as opposed to the REST endpoint 访问 URL .
    因此,您的 Cloudfront 分发源必须配置为 Origin type = Custom Origin指向一个域,例如 example.com.s3-website.us-east-1.amazonaws.com , 不是 作为 S3 Origin .
    如果您的 Cloudfront/S3 配置错误,当您点击“尾部斜杠”样式的 URL 时 - 您可能会看到您的浏览器下载了 binary/octet-stream 类型的文件。包含 0 bytes .

    编辑 : 小心带有 . 的页面字符,根据 issue 16617 .

    关于amazon-web-services - Next.js:托管在 AWS Cloudfront 上时,如何使链接与导出的站点一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63591544/

    相关文章:

    google-chrome - 如何从 Chrome 中删除 "is dangerous, so Chrome has blocked it" block ?

    javascript - NextJS - onClick 时调用 js 函数

    Next.js CORS 问题

    reactjs - 在 next.js 的自定义 _app 组件中使用 `getInitialProps ` 是否会禁用客户端渲染?

    amazon-web-services - 如何将 elasticache redis 集群设置为从属?

    jquery - 亚马逊云搜索查询

    file-upload - Jquery 文件上传 - 如何限制上传的文件数量

    amazon-web-services - 使用 AWS CloudFormation estimator-template-cost 获取实时 CloudFormation 堆栈的估计成本

    amazon-web-services - 如何自动将自动扩展的 EC2 实例添加到安全组?

    google-chrome - 在 Chrome 上从 S3 下载 PDF 的问题