36

我在 S3 中托管一个静态网站并使用 Cloudfront 来缓存文件。我基本上有 3 个带有以下标题的文件:

  • index.html(缓存控制:无缓存)
  • app.js (缓存控制: max-age=63072000, public)
  • style.css (缓存控制: max-age=63072000, public)

我的 html 文件使用每次更新我的 css 或 js 文件时都会更新的查询字符串参数。我已经将 s3 配置为传递这些参数,并且我已经验证它可以使缓存的资源无效。我的 index.html 文件看起来像这样:

<html>
    <head>
        ...
        <link rel="stylesheet" href="app.css?v=14113e2c764">
    </head>
    <body>
        ...
        <script src="app.js?v=14113e2c764"></script>
    </body>
</html>

当我整天推送更新时,它似乎工作得很好,但是当我第二天早上来推送我的下一个更改时,index.html 文件已经过时了。它没有正确的 ?v= 参数,而是旧的!修复它的唯一方法是手动使 html 文件无效。然后在一天的剩余时间里一切正常。第二天我又遇到了同样的问题。

这里发生了什么?

4

2 回答 2

57

验证 CloudFront 分配Minimum TTL是否设置为 0。如果将其设置为任何其他值,CloudFront 将不遵守no-cache标头,仍会为Minimum TTL. 可以在此处找到有关缓存指令的更多详细信息:

http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Expiration.html

如果这没有帮助,请尝试调试实际的 HTTP 请求index.html并在此处发布响应标头,以便我们查看它们。

no-cache此外,您可以尝试使用而不是使用index.html 文件

public, must-revalidate, proxy-revalidate, max-age=0

这将允许 CloudFront 将文件存储在边缘站点上,但它会强制它使用每个请求的源重新验证它。如果文件未更改,CloudFront 将不需要从源传输文件的全部内容。这可以加快响应时间,尤其是对于较大的文件。

于 2013-09-13T06:09:11.313 回答
4

这更像是一个评论,但有点太长了。希望能帮助其他登陆这里的人。

通过查询参数破坏缓存有缺点,尽管您可以通过 Cloudfront 行为来对抗它们。请参阅https://stackoverflow.com/a/24166106/630614。不过,我会推荐唯一的文件名,例如app.css?v=14113e2c764变成app.14113e2c764.css.

回复 BradLaney 的评论/问题:如果您更新了缓存控制标头但没有看到更改,那是因为原始项目已被缓存- 使其无效,您应该在下次查看资源时看到新标头.

关于为 S3 项目设置缓存控制时的竞争条件,或者只是为 SPA 设置缓存控制,这对我的团队来说效果很好:

# Sync all files with 1 week cache-control, excluding .html files.
aws s3 sync --cache-control 'max-age=604800' --exclude *.html dist/ s3://$AWS_BUCKET/
# Sync remaining .html files with no cache.
aws s3 sync --cache-control 'no-cache' dist/ s3://$AWS_BUCKET/
于 2020-08-12T16:55:41.570 回答