浏览器缓存在S3 + Cloudfront上肆虐

时间:2018-03-23 19:10:25

标签: caching amazon-s3 browser-cache amazon-cloudfront

我在S3 + Cloudfront上托管了一个静态网站。要重新部署,我使用

上传静态文件
aws s3 sync static

并使用

使cloudfront缓存无效
aws cloudfront create-invalidation

在我更新这些新资产后强制浏览器获取这些新资产的推荐方法是什么?问题是浏览器正在缓存这些资产,而用户正在使用旧的(无效)版本的脚本,图像和样式。

2 个答案:

答案 0 :(得分:6)

通常,您可以采取多个步骤来确保您的AWS CloudFront和S3设置在新部署时缓存。

  • 确保使index.html的缓存无效(如果已缓存)
  • 您可以拥有静态资产的查询参数或新文件名,例如JavaScript,CSS&等

使用新文件名

<!doctype html>
<html lang="en">
  <head>
     <link href="styles.h2d1f722.css" rel="stylesheet" />
  </head>
  <body>
     <script type="text/javascript" src="scripts.cbe3c974.js"></script>
  </body>
</html>

您可以使用前端构建工具(例如Webpack,Gulp&amp;等)生成新文件名。

使用查询参数

<!doctype html>
<html lang="en">
  <head>
     <link href="styles.css?hash=h2d1f722" rel="stylesheet" />
  </head>
  <body>
     <script type="text/javascript" src="scripts.js?hash=cbe3c974"></script>
  </body>
</html>

设置查询参数时,请确保已在CloudFront中启用它(否则将返回文件的缓存响应)。

注意:比较这两种方法,每种方法都有利弊。使用相同的文件名,您可以在使用新的名称时使用S3本机版本对文件进行版本化,因为新部署为文件添加了新名称,所以这样做没有多大意义。除了将旧文件移除或移动到另一个存储桶之外,使用新文件名也会使S3存储桶变得混乱。

  • 确保index.html(Cache-Control,Expires和Pragma Headers)中有适当的Meta标签值。

使用元标记

<!doctype html>
<html lang="en">
  <head>
     <meta http-equiv="cache-control" content="max-age=0" />
     <meta http-equiv="cache-control" content="no-cache" />
     <meta http-equiv="expires" content="0" />
     <meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT" />
     <meta http-equiv="pragma" content="no-cache" />
     <link href="styles.css?hash=h2d1f722" rel="stylesheet" />
  </head>
  <body>
     <script type="text/javascript" src="scripts.js?hash=cbe3c974"></script>
  </body>
</html>

在此示例中,它指示不在浏览器中缓存。但是,您可以为这些设置适当的值。

  • 练习静态资产的版本控制方案,这样即使将最新版本的index.html提供给最终用户(从浏览器缓存),网页仍会加载旧资产(JS,CSS&amp;没有任何问题。

答案 1 :(得分:1)

除非手动干预,否则如果浏览器已经保留缓存值,则无法强制它们。

你需要追加

  

script.something.js?buildid = someuniquereference

并使cloudfront不要缓存查询字符串参数。

您还可以包含filename.hash.js或filename.hash.html以及index.html / default文档,减少缓存控制标头的缓存时间。

这样,如果您进行任何更改,您可以更改该数字,缓存也将在客户端上被破坏。

但是一旦发送了缓存标头,就无法远程清理浏览器上的客户端缓存。

希望它有所帮助。