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

Posted

技术标签:

【中文标题】您如何使托管在 S3 上的静态站点的 index.html 缓存失效?【英文标题】:How do you invalidate cache of index.html for a static site hosted on S3 with cloudfront? 【发布时间】:2016-05-27 10:25:50 【问题描述】:

因此,我在 s3 上使用 cloudfront dist 托管了我的 angular 应用程序。我做文件修订(使用 grunt filerev)以确保我永远不会得到过时的内容。但是,我应该如何对 index.html 文件进行版本控制。它是必需的,因为所有其他文件都在 index.html 中引用。

我已将存储桶配置为用作静态站点。因此,当我在 url 中引用存储桶时,它只会获取 index.html。

Cloudfront 说您应该将 min TTL 设置为 0,因此它总是会命中源来提供内容。但是,我不需要这个,因为我正在对所有文件(index.html 除外)进行文件修订。我可以利用这些文件的 cdn 缓存。

他们还说,为了使单个对象无效,请将 max-age 标头设置为 0。我尝试将以下内容添加到我的 index.html

<meta http-equiv="Cache-Control" content="public, must-revalidate, proxy-revalidate, max-age=0"/>

但这并不会在您上传到 s3 后反映出来。我是否需要使用 s3cmd 或仪表板在 s3 上显式设置标头?每次 index.html 更改并上传时我都需要这样做吗?

我知道我可以使用 cmd 使单个文件无效,但它是一个重复的过程,如果它可以通过部署在 s3 上自行处理,那就太好了。

【问题讨论】:

相关:How to purge CloudFront's cache. 【参考方案1】:

虽然如果您使用的是 s3cmd,则接受的答案是正确的,但我使用的是 AWS CLI,所以我所做的是以下 2 个命令:

首先,实际部署代码:

aws s3 sync ./ s3://bucket-name-here/ --delete

然后,在 CloudFront 上创建失效:

aws cloudfront create-invalidation --distribution-id &lt;distribution-id&gt; --paths /index.html

【讨论】:

谢谢@Jordan。我正在尝试这个但没有得到想要的结果。 aws cloudfront create-invalidation --distribution-id $CLOUDFRONT_ID --paths '/index.html'。还有什么想法吗? 我会检查您的云端分发日志,看看是否触发了失效,并确保那里正确显示了路径。 来自云端分发的失效详细信息与其他详细信息一起显示了这一点 objects path /index.html /service-worker.js。我正在部署启用服务人员的反应应用程序 如果我使--paths /*无效,日志会显示这个object paths /lib /tmp /srv /root /media /opt /mnt /etc /usr /dev /var /sbin /proc /bin /run /sys /home /boot /lib64 没有必要为了使 index.html 失效而使整个存储桶失效。【参考方案2】:

回答我自己的问题。我使用 s3cmd tool 将我的站点部署到 S3,并且您可以提供一个选项来使所有更改的文件的 CloudFront 缓存无效(您的 dist 文件夹和 S3 存储桶之间的差异)。这会使包括索引文件在内的所有已更改文件的缓存无效。通常需要大约 15-20 分钟才能反映生产中的新变化。

这是命令

s3cmd sync --acl-public --reduced-redundancy --delete-removed --cf-invalidate [your-distribution-folder]/* s3://[your-s3-bucket]

注意:在 macOS 上,您可以通过以下方式安装此工具:brew install s3cmd

希望这会有所帮助。

【讨论】:

您必须在[your-distribution-folder]/* 中指定什么?这与 CloudFront 分配 ID 相同吗?**域名**?还是ARN?这些是我看到的字段 (i.imgur.com/8IEEYmS.jpg),但我尝试了一堆,它一直给我ERROR: Parameter problem: Invalid source: 'WHATEVER_I_TRIED' is not an existing file or directory(如果重要的话,在 Windows 上)。 还需要/* 吗?这是否意味着分发/存储桶中的所有内容都失效了? 它应该是您配置为网站根目录的存储桶/文件夹的名称。 没有。它不会使一切无效。它使用同步命令检查文件中的差异,并且仅使已更改的文件无效。【参考方案3】:

您可以使用 Lambda 自动化流程。它允许您创建一个函数,该函数将执行某些操作(在您的情况下为对象失效)以响应某些事件(S3 中的新文件)。

更多信息在这里: https://aws.amazon.com/documentation/lambda/

【讨论】:

在 /index.html 手动失效后,我得到了我的应用程序的以前版本。你能做到吗? 这是一个帮助我快速设置的要点:gist.github.com/supinf/e66fd36f9228a8701706(我不是创作者,所以如果它不能开箱即用,我真的帮不上忙!)【参考方案4】:

当你用 s3 同步本地目录时,你可以这样做:

aws s3 sync ./dist/ s3://your-bucket --delete

aws s3 cp \
   s3://your-bucket s3://your-bucket \
   --exclude 'index.html' --exclude 'robots.txt' \ 
   --cache-control 'max-age=604800' \
   --metadata-directive REPLACE --acl public-read \
   --recursive

第一个命令只是普通同步,第二个命令使 S3 能够为除index.htmlrobots.txt 之外的所有文件返回缓存控制。

然后您的 SPA 可以被完全缓存(index.html 除外)。

【讨论】:

【参考方案5】:

我在 S3 上托管并使用 CloudFront 分发的静态网站也遇到了同样的问题。在我的情况下,使 /index.html 无效是无效的。

我与 AWS 支持人员进行了交谈,我需要做的就是仅使用 / 使无效。这是因为我使用 https://website.com/ URL 而不是 https://website.com/index.html 访问我的网站(这会带来带有 /index.html 失效的更新内容)。这是在 AWS CloudFront 控制台中完成的,而不是使用 AWS CLI。

【讨论】:

【参考方案6】:

如果您使用s3cmd sync 并使用--cf-invalidate 选项,您可能还需要指定--cf-invalidate-default-index,具体取决于您的设置。

来自手册页:

使用Custom Origin和S3静态网站时,默认索引文件无效。

这将确保您的索引文档也无效,很可能是 index.html,否则无论是否通过同步更新,都会跳过该文档。

【讨论】:

以上是关于您如何使托管在 S3 上的静态站点的 index.html 缓存失效?的主要内容,如果未能解决你的问题,请参考以下文章

如何在AWS中为自己的S3托管站点添加SSL/TSL证书(https)

AWS S3 静态站点 CORS jquery ajax POST 到 API Gateway

我如何将 domain.com 转发到 godaddy 上的 www.domain.com 以获取 s3 托管站点?

如何使 CloudFront 永远不会在 S3 存储桶上缓存 index.html

如何主持静态网站只有cognito和s3

在 S3 + Cloudfront 上以相同的 URL 托管多个 SPA Web 应用程序