随着时间的推移,CloudFront 上的静态内容缓存不正确

Static content on CloudFront is cached incorrectly over time

我已经在多个 S3 存储桶(在不同地区)之上设置了一个 CloudFront,以提供我的 web 应用程序的快速稳定版本。这个 webapp 是用 React 实现的,这意味着它是一个 HTML 文件和一个 Javascript 文件。

利用React的路由机制,URL中的所有路径都在代码内部处理。这意味着如果我单击 link,例如 www.example.com/users,将不会向服务器发送请求。相反,客户端代码将在不与服务器进行任何协商的情况下呈现适当的页面(我只是在谈论 HTML 而不是考虑数据)。这意味着如果某些用户在给定 URL 中键入,服务器应该 return index.html(我拥有的唯一 HTML 文件),然后它将处理 URL 在客户端。换句话说,所有发送到服务器的请求应该是 return HTML 文件或我前面提到的 Javascript 文件。即使是指向 none- 现有文件的请求。

为了实现这个需求,我问了this question,得到的答案是这样的:

I need to set up an error page for my distribution on CloudFront and redirect all the 403 (Forbidden) requests to /index.html file. This is because when the request is pointing to a nonexisting file on S3, S3 will return 403 to CloudFront due to the lack of listing permission. Or I can grant the listing permission and instead handle the 404 error (I didn't test this latter option).

无论如何,我设置了它并且它完美地工作了几个小时。但是,出于某种未知原因,对 Javascript 文件的请求也 return 是 HTML 文件。当然,我返回的所有内容实际上都来自 CloudFront 的缓存,这意味着无论我发送请求多少次,它都会保持 returning 相同的值。直到我使 CloudFront 上的缓存无效,这将再解决几个小时的问题。然后我们兜兜转转。

尽管我不确定为什么会发生这种情况,但我的猜测是在某些时候 CloudFront 无法访问 S3 buck,这将导致 CloudFront 缓存 index.html。我该怎么办?

我想我发现了问题:

确保所有 S3 存储桶上的静态内容都相同!!!

在我的例子中,Javascript 文件名是由 Webpack 自动生成的,这意味着它是随机的。由于不同的区域被 "compiled" 分开,它们的文件名也不同。