您如何使托管在 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 <distribution-id> --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.html
和robots.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 托管站点?