在 S3 上刷新页面会抛出 "access denied" 错误,但如果我使用原点则不会

Refreshing page on S3 throws "access denied" error but not if I use the origin

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

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

我做到了 public 并且启用了静态网站托管。我还在 Cloudfront 中将默认对象设置为 index.html。

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

- /index.html

- /articles
-- index.html

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

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

基本上每个路径都有自己的 index.html(NextJS 的常见设置)。我读到一个 404 问题还设置了一个 404 错误页面,如 question about 404 中所述。然而并没有解决问题。

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

请指教

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

例如,您在 ./pages/blog/[slug].tsx 中有一个 Next.js 博客,您希望通过 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;
}

我明白了。由于没有人能够回答它,所以我想到了对我有帮助的东西。我的网站托管在启用了静态托管的 S3 上。我从那里复制了原点 url (没有 http:// 部分)。然后我去了 cloudfront,在设置原点时,我粘贴了 S3 static URL(没有 http:// 部分)。如果您托管的是静态网站,请不要从下拉列表中选择来源。下拉列表指向 S3 的 REST API 端点,在这种情况下不起作用。更多信息在这里:https://aws.amazon.com/premiumsupport/knowledge-center/cloudfront-serve-static-website/