Amazon web services 如何使CloudFront从不在S3 bucket上缓存index.html
我有一个在S3存储桶上托管的React应用程序。使用Amazon web services 如何使CloudFront从不在S3 bucket上缓存index.html,amazon-web-services,amazon-s3,amazon-cloudfront,Amazon Web Services,Amazon S3,Amazon Cloudfront,我有一个在S3存储桶上托管的React应用程序。使用纱线构建(这是一个基于create-react的应用程序)缩小代码。build文件夹看起来像: build ├── asset-manifest.json ├── favicon.ico ├── images │ ├── map-background.png │ └── robot-icon.svg ├── index.html ├── js │ ├── fontawesome.js │ ├── packs │ │ ├─
纱线构建(这是一个基于create-react的应用程序)缩小代码。build
文件夹看起来像:
build
├── asset-manifest.json
├── favicon.ico
├── images
│ ├── map-background.png
│ └── robot-icon.svg
├── index.html
├── js
│ ├── fontawesome.js
│ ├── packs
│ │ ├── brands.js
│ │ ├── light.js
│ │ ├── regular.js
│ │ └── solid.js
│ └── README.md
├── service-worker.js
└── static
├── css
│ ├── main.bf27c1d9.css
│ └── main.bf27c1d9.css.map
└── js
├── main.8d11d7ab.js
└── main.8d11d7ab.js.map
我永远不想缓存index.html
,因为如果我更新代码(导致main.*.js
中的十六进制后缀更新),我需要用户下次访问时查看index.html
中的
更改以指向更新的代码
在CloudFront中,我似乎只能排除路径,而排除“/”似乎无法正常工作。当我改变代码时,我会有一种奇怪的行为,如果我点击refresh,我会看到它,但是如果我退出Chrome并返回,我会因为某种原因看到非常过时的代码
我不想在每次代码发布时都触发失效(通过CodeBuild)。还有别的办法吗?我认为其中的一个挑战是,由于这是一个使用React Router的应用程序,我不得不做一些诡计,将错误文档设置为index.html
,并强制HTTP状态为200而不是403。如果您永远不想缓存index.html
,请仅在该文件上设置缓存控制:max age=0
头。CloudFront将在每次请求时向您的原始S3存储桶发出请求,但听起来这是您想要的行为
如果要设置更长的过期时间并手动使CloudFront缓存无效,可以使用*
或/*
作为无效路径(而不是您提到的/
)。但是,世界各地的所有CloudFront edge节点最多需要15分钟才能反映您的源站点中的更改。以下是我在将新文件上载到s3并使CloudFront无效后为设置index.html文件的缓存控制而运行的命令:
aws s3 cp s3://bucket/index.html s3://bucket/index.html --metadata-directive REPLACE --cache-control max-age=0
基于CloudFront配置的解决方案:
转到CloudFront发行版的“行为”选项卡下,创建新的行为。
指定以下值:
- 路径模式:index.html
- 对象缓存:自定义
- 最大TTL:0(或另一个非常小的值)
- 默认TTL:0(或另一个非常小的值)
保存此配置
CloudFront将不再缓存index.html
。在每个版本上运行index.html的无效声明要比违背CloudFront的目的并每次从S3为其服务(这基本上是应用程序的入口点)要好得多。您是在谈论在S3对象元数据中添加该标头吗?正确的是,无论URL路径如何,我都不想缓存index.html。我更关心的是缓存相关文件(JS文件、CSS、图像)。是的:在AWS文档中它被称为“系统定义的元数据”:太好了,这很有帮助!我已将部署过程设置为在索引文件上复制时使用aws s3 cp--cache control max age=0
。工作起来很有魅力。我知道这些都是老问题和回答,但我已经通过为index.html.Life saver hack设置缓存控制:no store
头(作为S3文件中的元数据)实现了同样的功能。谢谢!但是,我需要添加——地区eu-central-1
,以使其正常工作谢谢我还必须添加-内容类型“text/html”
选项,否则我的index.html文件将作为二进制文件。Hi@seza443对内部目录中的index.html文件有效,还是仅对根目录中的文件有效?@TumainiMosha对此不确定。我会说只有根目录。要匹配所有子目录的index.html
,请尝试*index.html
?谢谢您的反馈。我可以确认初始规则(index.html
)适用于内部目录。我查看了cloudfront文档,基本上,它们的规则匹配文件名,即使是在内部目录中,而不仅仅是根目录中。如果其他人好奇:从AWS CLI实现这一点不是很方便。如果您使用的是CI/CD解决方案,并且您的index.html每次都会更新,那么这就是方法。问题是,一旦浏览器看到index.html没有设置为“不缓存”的缓存控制标头,那么浏览器在随后的调用中甚至不会转到服务器。因此,Cloudfront失效对现有用户没有任何作用。@UğurDinç“问题是,一旦浏览器看到index.html没有缓存控制头设置为不缓存,那么浏览器在后续调用中甚至不会转到服务器。”它实际上是这样做的,至少是Chrome。不过,为了使其更具确定性,您可以将标头添加到S3对象中。例如,如果将最小TTL设置为>0且大于最大年龄,Cloudfront将缓存对象以获取TTL值(而浏览器将使用最大年龄)。请参阅:我们发现,在使用无效时,并非所有边缘位置都被清除。我们希望将index.html标记为未验证(我们在Angular中构建了一个SPA,并注意到一些用户正在使用旧版本)。@jackofallcode我最近也注意到了同样的问题,您是否找到了解决此问题的方法?@asliwinski我们选择在CloudFront发行版上设置缓存行为,以不缓存index.html。使用Angular,它只有一个小的核心应用程序(JS和CSS)按预期进行缓存(新版本创建新文件,而不是更新现有文件)。这不是理想的解决办法。