简体   繁体   English

Amazon Cloudfront Cache-Control:no-cache 标头在 24 小时后无效

[英]Amazon Cloudfront Cache-Control: no-cache header has no effect after 24 hours

I'm hosting a static website in S3 and using Cloudfront to cache files.我在 S3 中托管一个静态网站并使用 Cloudfront 来缓存文件。 I've essentially got 3 files with the following headers:我基本上有 3 个带有以下标题的文件:

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

My html file uses query string parameters that get updated every time I update my css or js files.我的 html 文件使用每次更新 css 或 js 文件时都会更新的查询字符串参数。 I've configured s3 to pass these parameters through and I've verified that it works to invalidate cached resources.我已经配置了 s3 来传递这些参数,并且我已经验证它可以使缓存的资源无效。 My index.html file looks something like this:我的 index.html 文件看起来像这样:

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

It seems to work great as I push updates all day, but when I come in the next morning and push my next change, The index.html file is out of date.当我整天推送更新时,它似乎工作得很好,但是当我第二天早上来推送我的下一个更改时,index.html 文件已过时。 Instead of having the correct ?v= parameter, it has the old one!它没有正确的 ?v= 参数,而是旧的! The only way to fix it is to invalidate the html file manually.修复它的唯一方法是手动使 html 文件无效。 Then everything works for the rest of the day.然后一切都在当天剩下的时间里工作。 The next day I have the same problem again.第二天我又遇到了同样的问题。

What's going on here?这里发生了什么?

Verify that the CloudFront distribution's Minimum TTL is set to 0. If it's set to any other value, CloudFront won't respect the no-cache header and will still cache the file for the Minimum TTL .验证 CloudFront 分配的Minimum TTL是否设置为 0。如果设置为任何其他值,CloudFront 将不会遵守no-cache标头,并且仍会缓存Minimum TTL的文件。 More details about the caching directives can be found here:可以在此处找到有关缓存指令的更多详细信息:

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

If this doesn't help, try to debug the actual HTTP request for index.html and post the response headers here so we can have a look at them.如果这没有帮助,请尝试调试index.html的实际 HTTP 请求并在此处发布响应标头,以便我们查看它们。

Also, instead of using no-cache for the index.html file, you can try using此外,您可以尝试使用,而不是对 index.html 文件使用no-cache

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

This will allow CloudFront to store the file on the edge location, but it will force it to revalidate it with the origin with each request.这将允许 CloudFront 将文件存储在边缘站点上,但它会强制它使用每个请求的源重新验证它。 If the file hasn't changed, CloudFront will not need to transfer the file's entire content from the origin.如果文件未更改,CloudFront 将不需要从源传输文件的全部内容。 This can speed up the response time, especially for larger files.这可以加快响应时间,尤其是对于较大的文件。

This is more of a comment, but a bit too long.这更像是评论,但有点太长了。 Hopefully helps others that land here.希望能帮助到这里的其他人。

Cache busting via query parameter has drawbacks, although perhaps you can combat them all via Cloudfront behaviors.通过查询参数清除缓存有一些缺点,但也许您可以通过 Cloudfront 行为来对抗它们。 See https://stackoverflow.com/a/24166106/630614 .请参阅https://stackoverflow.com/a/24166106/630614 Still, I would recommend unique filenames eg app.css?v=14113e2c764 becomes app.14113e2c764.css .不过,我会推荐唯一的文件名,例如app.css?v=14113e2c764变成app.14113e2c764.css

To respond to BradLaney's comment/issue: If you've updated cache-control headers and don't see the changes, it's because the origin item is already cached – invalidate it and you should see the new headers the next time you view the resource.回应 BradLaney 的评论/问题:如果您更新了缓存控制标头但没有看到更改,那是因为原始项目已被缓存– 使其无效,您应该在下次查看资源时看到新标头.

Regarding race condition when setting cache-control for S3 items, or just setting cache-control in general for an SPA, this is what's working well for my team:关于为 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/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM