首页 > 解决方案 > S3 上的刷新页面会引发“访问被拒绝”错误,但如果我使用原点则不会

问题描述

我有一个托管在 AWS 上的 NextJS 应用程序。我已将我的域配置为指向 Cloufront 并指向 S3 源存储桶。我已将此策略添加到我的 S3 存储桶中:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicRead",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:GetObject",
                "s3:GetObjectVersion"
            ],
            "Resource": "arn:aws:s3:::<mybucket>/*"
        }
    ]
}

我已将其公开并启用了静态网站托管。我还在 Cloudfront 中将默认对象设置为 index.html。

所以发生的事情是,当我进入我的域时,主页会加载,只要我点击链接,我就可以到达该页面。但是只要我点击刷新,我就会收到 S3AccessDenied消息。我的文件夹结构是这样的:

- /index.html

- /articles
-- index.html

-- /article1
---- /index.html

-- /article2
---- /index.html
.
.
.

基本上每条路径都有自己的 index.html(与 NextJS 共同设置)。我读到了一个 404 问题,还设置了一个 404 错误页面,正如这个关于 404的问题中提到的那样。然而它并没有解决问题。

然后我尝试通过 S3 原始 URL 直接访问我的网站,一切都按预期工作,包括页面刷新。所以,我在想我的域和 S3 源之间的映射不起作用,但我不确定它是什么。是在 Cloudfront 还是 S3 策略上还是其他什么东西上。

请指教。

标签: amazon-web-servicesamazon-s3next.jsamazon-cloudfront

解决方案


有一个使用 Cloudfront 函数的解决方法。

例如,你有一个 Next.js 博客./pages/blog/[slug].tsx,你想直接通过它访问它,https://example.com/blog这样它也可以在刷新时工作。

您必须将请求从 /blog 重定向到 /blog.html

将此作为查看器请求函数添加到分发的默认行为中。

function handler(event) {
    var request = event.request;
    var uri = request.uri;
    if (uri !== '' && uri !== '/' && uri.indexOf('.') === -1) {
        request.uri = uri + '.html';
    }
    return request;
}

推荐阅读