我们在尝试使用客户端路由器(反应路由器)运行 SPA 时遇到问题。我们使用
DOMAIN -> CDN (CloudFront) -> S3
的概念来服务我们的静态文件。
我们已将 S3 配置为提供静态文件。 CDN 配置为源自 S3,并且我们配置了自定义错误页面来捕获错误:
通过此配置,我们可以捕获如下错误:
https://www.example.com/custom-url
CDN 会将所有 404/403 错误重定向到主
index.html
,并且 react router
将获得正确的路由。
我们的站点正在运行,客户端路由器工作正常,但我们的 CDN 响应存在问题,
x-cache: Error from cloudfront
:
如果我们在没有任何查询参数(不是查询字符串)的情况下访问主网址
https://www.example.com
,一切正常。
如何解决这个问题并使我的所有动态 URL 都正常工作?
谢谢。
当您访问
http://mywebsite.com
时,请求将到达 S3 中的 index.html
文件。然后您可以单击一个按钮并转到 http://mywebsite.com/stats
,这是 SPA 应用程序的内部路径。因此,它不会触发任何后端请求。
但是如果您重新加载页面,
http://mywebsite.com/stats
将被发送到 S3,因为您的浏览器不知道您正在运行 SPA 前端。
S3 将返回 403 错误以及 index.html,Cloudfront 将向您发送该错误。
解决方案是在 Cloudfront 中使用边缘 lambda 函数。这是一个例子:
const path = require('path')
exports.handler = (evt, ctx, cb) => {
const {request} = evt.Records[0].cf
if (!path.extname(request.uri)) {
request.uri = '/index.html'
}
cb(null, request)
}
Amazon CloudFront 的配置和调试错误代码可能会很棘手 - 追溯其根本原因可能需要几个小时。但是,您可能需要在进入日志之前进行以下检查。
存储桶名称应与您托管的网站的名称匹配。
例如,要在 Amazon S3 上托管 your-domain.com 网站,您需要创建一个名为 your-domain.com 的存储桶。
要在 www.your-domain.com 下托管网站,您可以将该存储桶命名为 www.your-domain.com。
最佳实践是为 your-domain.com 和 www.your-domain.com 创建存储桶。
在您的设置/配置中为这些存储桶中的任何一个使用现有逻辑,并使用它来为静态网站提供服务。使用另一个存储桶将请求重定向到原始存储桶。
老实说,这不会给您带来麻烦,因为您已将系统与 Amazon CloudFront 集成,可以将其配置为使用任何名称的 Amazon S3 存储桶。
使用 Amazon CloudFront,访问您域的用户将直接从 CloudFront 分配获取数据,而 CloudFront 分配又会缓存我们的 S3 存储桶中的内容。
使用 Amazon CloudFront 创建分配时,请记下关联的 Amazon S3 终端节点和源域名。确保使用网站端点,而不是 REST 端点。不要使用 CloudFront 自动建议的端点。 Amazon Web Services
官方文档而 404 只是页面未找到的结果。但是,在错误重定向之后(如您的配置中处理的那样),用户将被重定向回
index.html
,在那里遇到 403。
有关以下内容的更多信息:CloudFront 如何处理和缓存来自您源的 HTTP 4xx 和 5xx 状态代码其他常见的可疑之处包括 Amazon CloudFront 分发的缓存配置、AWS Route53 设置和 Amazon Certificate Manager。
感谢您的阅读。
function handler(event){
// Check if the request is for an internal route (doesn't have a file extension)
if (!event.request.uri.includes('.')) {
event.request.uri = '/index.html';
}
return event.request;
}