我在S3中托管静态网站,并使用Cloudfront缓存文件。我基本上有3个文件,包含以下标题:
我的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文件无效。然后一切都适用于其余的一天。第二天我又遇到了同样的问题。
这里发生了什么?
答案 0 :(得分:41)
验证CloudFront分配的Minimum TTL
是否设置为0.如果将其设置为任何其他值,CloudFront将不会尊重no-cache
标头,并仍将缓存{{1}的文件}。有关缓存指令的更多详细信息,请访问:
http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Expiration.html
如果这没有帮助,请尝试调试Minimum TTL
的实际HTTP请求并在此处发布响应标头,以便我们查看它们。
此外,您可以尝试使用
,而不是将index.html
用于index.html文件
no-cache
这将允许CloudFront将文件存储在边缘位置,但它会强制它使用每个请求的原点重新验证它。如果文件未更改,CloudFront将不需要从源文件传输文件的整个内容。这可以加快响应时间,尤其是对于较大的文件。
答案 1 :(得分: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/