我试图通过做一个 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,
}
根据 documentationexport 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/