Amazon s3 静态 Web 托管缓存

Posted

技术标签:

【中文标题】Amazon s3 静态 Web 托管缓存【英文标题】:Amazon s3 static web hosting caching 【发布时间】:2017-07-20 18:36:27 【问题描述】:

我正在为我的静态 html、js、css(等等)文件使用 Amazon S3 网络托管。 替换我的 index.html 文件后,通过浏览器使用时我仍然得到旧版本。 我想将默认 ttl 设置为存储桶(而不是设置为其中的特定对象)。我找到了这个链接: http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/distribution-web-values-specify.html#DownloadDistValuesDefaultTTL

但在仪表板中找不到“对象缓存”设置。有人可以指出它在哪里吗?

【问题讨论】:

您引用的链接适用于 CloudFront,而不是 S3。如果您不使用 CloudFront,则此信息不相关。如果您使用的是 CloudFront,则应在问题中提及这一点。 相关:***.com/questions/22501465/… 【参考方案1】:

2022 AWS CLI V2 方法

实现此目的的最简单方法是使用AWS CLI (S3)。这也可以使用 GitHub actions 之类的工具完全免费地自动化。

静态站点不应将cache-control 设置为HTML 文件上的长期值,因为在浏览器缓存过期或手动破坏其缓存之前,用户将看不到更新的版本。


由于 AWS CLI 的限制,您必须执行以下操作才能为整个存储桶设置缓存。


一般示例

上传内容和--delete旧S3内容,并在所有内容上设置cache-control

aws s3 sync [YOUR_LOCAL_SOURCE_CODE_PATH] s3://[BUCKET_NAME] --delete --cache-control max-age=31536000

从所有HTML 文件中递归删除cache-control 标头并将文件设置回类型HTML.

aws s3 cp s3://[BUCKET_NAME] s3://[TO_BUCKET_NAME] --recursive --exclude "*" --include "*.html" --metadata-directive REPLACE --cache-control max-age:no-cache --content-type text/html

备注

TO_BUCKET_NAME 几乎总是与 BUCKET_NAME 相同 如果您在 AWS S3 中修改 HTML 文件的元数据,您还必须设置 content-type,否则它将自动设置为通用类型,导致浏览器下载文件而不是在其中呈现它浏览器。

示例

// delete old files and upload files from the local directory to the s3 bucket, and set the cache-control header on every file.
aws s3 sync ./out s3://www.test.com --delete --cache-control max-age=31536000

// copy all files and remove cache control header from only HTML files and set back to html content type
aws s3 cp s3://www.test.com s3://www.test.com --recursive --exclude "*" --include "*.html" --metadata-directive REPLACE --cache-control max-age:no-cache --content-type text/html

// bonus - if using CloudFront - small site can invalidate all cache (/*)
aws cloudfront create-invalidation --distribution-id=123ABCDEFG --paths "/*"

【讨论】:

嗨,肖恩。只是对我所做的编辑的快速解释,然后您将其还原。如果您坚持要对另一个答案发表评论,那么您应该评论该答案当您获得特权时。不要使用答案来回应答案 - 这不是一个主题讨论论坛。我认为您所掌握的信息对 OP 和可能遇到相同问题的其他人有所帮助,因此值得将您的帖子调整为 听起来 像一个答案,并避免被删除。【参考方案2】:

如果您使用 AWS CLI,您可以为每个同步对象添加 --cache-control--metadata directive

这是我的 npm 脚本:

 "scripts": 
    "prod": "NODE_ENV=production webpack --config ./webpack.config.prod.js",
    "sync": "aws s3 sync public/ s3://[BUCKET_NAME] --delete --cache-control max-age=31536000",
    "invalidate": "aws cloudfront create-invalidation --distribution-id [DISTRIBUTION_ID] --paths \"/*\"",
    "deploy": "npm run prod && npm run sync && npm run invalidate"
  ,

【讨论】:

【参考方案3】:

这里有一个Amazon S3 link 可以回答您的问题。根据亚马逊的说法,除非您使用第三方工具(该页面链接到几个),否则您无法为整个存储桶设置缓存控制标头。我遇到的一个工具描述了如何为使用PUT 请求(或使用他们的工具批量提交)提交的对象设置缓存指令。有关更多信息,请参阅BucketExplorer。

这是亚马逊说明的剪切粘贴(因为 S.O. 不喜欢依赖可能会更改或消失的外部链接):

使用 Amazon S3 控制台向 Amazon S3 对象添加 Cache-Control 或 Expires 标头字段

    登录 AWS 管理控制台并打开 Amazon S3 控制台 https://console.aws.amazon.com/s3。 在 Amazon S3 控制台的存储桶窗格中,单击包含文件的存储桶的名称。 在对象列表中,选择要添加标头字段的第一个对象。 点击Actions,然后点击Properties。 在右侧窗格中,展开元数据。 点击添加更多元数据。 在 Key list 中,点击 Cache-ControlExpires(如果适用)。 在字段中,输入适用值: 对于缓存控制字段,输入:max-age=number of seconds that you want objects to stay in a CloudFront edge cache 对于 Expires 字段,输入 HTML 格式的日期和时间。 点击保存

如果要向其他对象添加标题字段,请单击下一个对象的名称,然后重复步骤 5 到 9。

【讨论】:

请注意,您也可以使用相同的过程在文件夹级别管理此行为。 在查看 Amazon S3 链接时为我添加了一些说明。如果您希望 Cloudfront 缓存而不是浏览器,请确保 s3 对象的 max-age 为零,但 Cloudfront 设置了最小 TTL 这工作正常,但是当我们推动新的构建和文件被替换时,它删除缓存头有什么办法可以自动设置这些文件的头【参考方案4】:

是的。如果您使用 CloudFront 分配 - 您只需要检查您的失效以及您的对象失效为何无法正常工作。什么是TTL值。

你使用 CDN 吗?

【讨论】:

设置 S3 Cache-Control 与设置 Cloudfront TTL 不同,后者仅控制文件在 Cloudfront 缓存中的停留时间。与浏览器缓存无关。

以上是关于Amazon s3 静态 Web 托管缓存的主要内容,如果未能解决你的问题,请参考以下文章

Amazon S3 静态托管自定义域

在 Amazon S3 中托管静态网站而不使用 Amazon 路由 53

为啥托管静态网站时 Amazon S3 存储桶名称必须与网站名称相同

您如何使托管在 S3 上的静态站点的 index.html 缓存失效?

尝试使用 cloudfront 和 privateKey 访问存储在 S3(静态 Web 托管)中的私有内容时获得 HTTP/1.1 403 Forbidden

从静态网页上传 csv 文件到 S3 存储桶