如何配置 CloudFront 以在更新时从 S3 更新 SPA?

How do I configure CloudFront to update SPA from S3 when updated?

我在 S3 上有一个 React SPA 应用程序。我使用 CloudFront 只是为了获得带有自定义域的 SSL 证书 - 老实说,我并不真正关心 CloudFront 的缓存功能,尽管我认为这是一个很好的好处。

一切正常,除了当我对 S3 存储桶进行更新时,页面仍缓存在 Chrome 中。如果我清除 Chrome 中的应用程序内存,它会熄灭并获取最新版本。

我正在通过创建生产版本来部署应用程序,然后将所有内容上传到 S3 并发出 CF 失效:

  echo "Pushing to S3."
  aws s3 sync --acl public-read ./ s3://${DEPLOY_BUCKET} --metadata-directive REPLACE --cache-control 'max-age=0,public,s-maxage=2'

  echo "Invalidating CloudFront cache."
  aws cloudfront create-invalidation --distribution-id ${DEPLOY_DISTRIBUTION} --paths '/' '/index.html' '/login' '/*'

对 CloudFront 的请求对我来说似乎 return 合理 header:

accept-ranges: bytes
cache-control: max-age=0,public,s-maxage=2
content-length: 716
content-type: text/html
date: Wed, 18 May 2022 17:15:36 GMT
etag: "660fb0d86eb442f658af12ead96b2c83"
last-modified: Wed, 18 May 2022 16:55:25 GMT
server: AmazonS3
via: 1.1 ....cloudfront.net (CloudFront)
x-amz-cf-id: eLXohvep_...==
x-amz-cf-pop: BOS50-C1
x-amz-version-id: 8V0DR...
x-cache: Miss from cloudfront

特别是 - cache-control header 显示 max-age 为 0,所以我认为应该告诉 Chrome 不要缓存东西并总是出去检查一个新版本。

CloudFront 设置为使用来源 headers,因此它应该从 S3 中提取这些内容。

我错过了什么?如何让 Chrome/CloudFront/S3 始终检查应用程序的最新版本?

由于 CloudFront 上的缓存 headers 很好,并且禁用 registerServiceWorker() 可以解决您的缓存问题,我们可以将责任归咎于服务工作者保持陈旧的内容。

registerServiceWorker() 可能来自 react-scripts < 4.0.0,这不允许您在不弹出或使用变通方法的情况下配置 service worker。如果您无法升级,您可能只想取消注册或删除服务工作者。

如果你升级到react-scripts >= 4.0.0,你可以modify the workbox config from the PWA Create React App template to use the NetworkFirst Workbox strategy. After upgrading, the precache and the waiting state of the service worker may still be too aggressive for your liking, in which case you should see if someone ran into the same PWA issue

Learn more about progressive web apps in Create React App

Learn more about how to troubleshoot Workbox