在管理缓存的同时使用 CloudFront 在 S3 上部署 React 应用程序的步骤?

Cha*_*man 5 amazon-s3 amazon-web-services amazon-cloudfront reactjs

我需要使用 SSL 和管理缓存在 AWS S3 上部署 React 应用程序。需要哪些步骤,我可能会遇到哪些问题?

Cha*_*man 14

为什么要这样做?

它可以非常快,“无服务器”并且非常便宜。通过 CloudFront 全局端点(边缘站点),应用程序可以非常快速地运行并具有高可靠性。通过设置另一个源源,CloudFront 可以充当 API 的反向代理,从而消除跨区域 (CORS) 问题并加速远程位置的 API 调用。多个部署可以上传到单个 S3 存储桶。

基本概念

在将 Create React App 部署到 S3/CloudFront 时,需要记住许多概念:

  • CloudFront 前端- 对于自定义域,SSL 流量将通过 CloudFront 而不是 S3(S3 不允许使用自定义域进行 SSL)
  • 一对多- 单个 S3 存储桶可以容纳多个部署(例如测试、生产)。我使用专用的 CloudFront 分配来设置每个部署,该分配指向相同的存储桶但具有不同的前缀(例如部署/测试、部署/生产)
  • 可以避免跨域 API 问题- 有一种方法可以将 CloudFront 用于 S3 中的静态文件和动态 API,它们都在同一个域中(见下文)
  • 压缩- 应始终在 CloudFront 上启用压缩
  • 浏览器缓存- CRA 构建将使用哈希键创建块文件。这些可以长时间缓存在浏览器中。但是没有散列键的文件index.html应该设置为无缓存。这些缓存属性可以通过 S3 设置。

跨域 API 问题 (CORS) - 如何避免

每个 CloudFront 分配都可以有多个源。一个源应该设置为 S3,而另一个可以设置为 API 服务器或负载均衡器。如果 API 服务器在 AWS 系统内,CloudFront 可以安全地使用非 SSL(端口 80)作为代理服务器进行通信。

要使用端口 80,必须将 API 服务器配置为响应非安全流量(如果流量仅为端口 80,则不需要 SSL 证书)。Apache VirtualHost 将使用 CloudFront 实例的主机名而不是API 服务器主机名(例如my.react-app.comnot my.api.com),因为 HTTP 请求主机值未修改。

要使用 CloudFront 启用 API:

  1. 将您的 API 服务器添加为源,仅当在 AWS 内时才添加 HTTP
  2. 添加新行为、/api/*路径模式、仅限 HTTPS 的查看器策略、所有 HTTP 方法(除非您只有 GET)、ALL针对基于选定请求标头的缓存、启用的压缩对象以及针对查询字符串的全部转发
  3. CloudFront 不应缓存任何内容(除非您可以执行此操作)

复制到 S3

将构建系统复制到 S3 的一种简单方法是:

aws s3 sync . s3://MY-S3-BUCKET/ --quiet
Run Code Online (Sandbox Code Playgroud)

这是相当有限的。它不会轻松管理浏览器缓存。可以删除(--delete选项)或维护(默认)旧文件;当然,这个工具知道应该为旧版本维护哪些 CRA 文件,因此垃圾收集会很复杂。

用于将 CRA 部署到 S3/CloudFront 的 Python 工具

我构建了一个 python 工具,它将:

  1. 上传任何新文件到 S3,验证 Etag 到 MD5
  2. 删除所有旧文件
  3. 可选择维护属于早期版本的旧precache-manifest文件(下载和解析旧文件)
  4. 为不同的文件设置HTTP缓存参数(即缓存带有hash键的文件,普通文件不缓存)
  5. 清除 CloudFront 分配(即失效请求)

即使您不使用它,它也可能对您的部署系统有所帮助。

在 CloudFront 中启用 React Router

要在 React Router 中启用不同的路径,请将 CloudFront 错误页面设置为/index.html(以便所有失败的请求都将转到那里):

  1. 在 AWS 控制台中转到 CloudFront 分配
  2. 单击相应的 CloudFront 分配
  3. 单击错误页面选项卡
  4. 添加错误响应403: Forbidden404: Not Found指向 /index.html的 HTTP 响应200

测试 HTTP 标头

如果您的 S3 存储桶设置为静态网站托管,您可以查看此 HTTP 标头(请注意,CloudFront 不需要 S3 网站托管即可工作):

curl -I http://MY-S3-ENDPOINT/index.html

同样,您可以测试来自 CloudFront 的标头:

curl -I https://CLOUDFRONT-URL/index.html

要测试压缩,请在请求 HTTP 标头中添加编码接受,例如

curl -H "Accept-Encoding: gzip" -I https://CLOUDFRONT-URL/index.html

  • 403 不应用作 404。请参阅本文 https://medium.com/faktiva/deploy-a-static-website-on-aws-the-right-way-e83f47d60fdc?source=friends_link&sk=e44dc908f1f86ee5caf06202cc8e (4认同)