【问题标题】:Amazon Cloudfront Cache-Control: no-cache header has no effect after 24 hoursAmazon Cloudfront Cache-Control:no-cache 标头在 24 小时后无效
【发布时间】:2013-09-17 10:02:40
【问题描述】:

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

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

我的 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 文件无效。然后在一天的剩余时间里一切正常。第二天我又遇到了同样的问题。

这是怎么回事?

【问题讨论】:

    标签: caching amazon-web-services amazon-s3 amazon-cloudfront


    【解决方案1】:

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

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

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

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

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

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

    【讨论】:

    • 看起来这是上传到 s3 的构建脚本中的竞争条件。我发送的标头不一致。
    • 将这些元标记添加到 index.html 文件后是否需要将最小 TTL 设置为 0?我们可以让其他文件的最小 TTL > 0 但不是 index.html 吗?
    • 如果您在 CloudFront 中定义了多个行为(例如,一个用于 index.html,另一个用于其余文件),您可以为 Minimum TTL 设置不同的值。请记住,在 CloudFront 中配置的 Minimum TTL 通常不是控制资源缓存时间的最佳解决方案。您通常应该在源服务器生成的响应中指定 Cache-Control 标头来控制这些响应并将 CloudFront 的最小 TTL 值保持为 0。
    • 24 小时是 Cloudfront 的默认行为,不能以任何方式被覆盖。好消息是,如果对象在原点没有改变,它不会重新获取对象,它将使用缓存中的内容,并重新开始 24 小时制。
    • 自定义选项中的最大 TTL = 0 似乎是可能的,以及从 24 小时开始更改时间。
    【解决方案2】:

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

    通过查询参数破坏缓存有一些缺点,但也许您可以通过 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/
    

    【讨论】:

      猜你喜欢
      • 2015-04-13
      • 2016-06-25
      • 2021-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-11
      • 1970-01-01
      • 2011-06-13
      相关资源
      最近更新 更多