Sho*_*orn 2 amazon-s3 amazon-web-services amazon-cloudfront next.js
我正在尝试通过执行静态 html 导出(即next export
),然后将生成的输出复制到 AWS S3 并通过 Cloudfront 提供服务来获得原型 Next.js 项目。
我在/pages
目录中有以下两页:
index.tsx
Pricing.tsx
然后,从路由 doco 开始,我Link
从索引页面向定价页面添加了一个,如下所示:
<Link href="/Pricing">
<a>Pricing</a>
</Link>
Run Code Online (Sandbox Code Playgroud)
这会产生一个看起来像这样的链接example.com/Pricing
(当您将鼠标悬停在它上面并单击该链接时,该页面确实会更改为定价页面,并且浏览器在 URL 栏中显示“example.com/Pricing”)。
问题是,该链接不是真实的 - 无法直接通过 url 栏添加书签或导航到它。
问题似乎是,当我执行 a 时next export
,Next.js.html
为每个页面生成一个文件,但路由器不使用这些.html
后缀。
因此,在使用该站点时,如果用户尝试添加书签example.com/Pricing
;稍后加载该书签将失败,因为 Cloudfront 将返回 404(因为 CF 只知道该.html
文件)。
然后我尝试改变我Link
的样子:
<Link href="/Pricing.html">
<a>Pricing</a>
</Link>
Run Code Online (Sandbox Code Playgroud)
这会导致路由器使用example.com/Pricing.html
并且与 Cloudfront 一起工作正常 - 但它实际上在本地开发期间导致 404(即使用next dev
)!
我可以尝试的其他解决方法是.html
在我将它们上传到 S3 之前重命名所有文件并删除扩展名(并确保它们得到一个content-type: text/html
标头) - 或者引入一个 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,
}
Run Code Online (Sandbox Code Playgroud)
根据文档
将页面导出为 index.html 文件并需要尾部斜杠,/about 变为 /about/index.html 并且可以通过 /about/ 路由。这是 Next.js 9 之前的默认行为。
所以现在您可以将Link
定义保留为:
<Link href="/Pricing">
<a>Pricing</a>
</Link>
Run Code Online (Sandbox Code Playgroud)
这会导致 Next.js 做两件事:
example.com/Pricing/
- 请注意/
末尾的index.html
在它自己的目录中生成每个页面- 例如/Pricing/index.html
许多 HTML 服务器在其默认配置中,index.html
如果/
在 URL 中看到尾随字符,就会从匹配目录内部提供。
S3 也会这样做,如果您将其设置为网站,并且IFF您通过网站端点访问 URL ,而不是 REST 端点。
所以,你的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。
归档时间: |
|
查看次数: |
1906 次 |
最近记录: |