【问题标题】:Client-side routing for S3 / Cloudfront with multiple path-based Single Page Apps具有多个基于路径的单页应用程序的 S3 / Cloudfront 客户端路由
【发布时间】:2021-08-08 19:30:40
【问题描述】:

我有以下情况:

  • 具有多个基于路径的应用程序的 S3 存储桶,按版本号分组。 简化示例:
/v1.0.0
  index.html
  main.js
/v1.1.0
  index.html
  main.js
  • 每个应用程序都是一个(React)SPA,需要客户端路由(通过 React 路由器)

我将 S3 与 Cloudfront 一起使用,并且大部分工作正常,但是客户端路由已损坏。这就是说我能够访问每个应用程序的根目录,即。 https://<app>.cloudfront.net/<version>,但无法到达任何客户端路由。

我知道 error document can be set 重定向到 index.html,但我相信此解决方案仅在每个存储桶有一个 index.html 时才有效(即,我无法为每个基于路由的路径设置错误文档)。

解决此问题的最佳方法是什么?

【问题讨论】:

    标签: amazon-web-services amazon-s3 react-router single-page-application amazon-cloudfront


    【解决方案1】:

    通过 Cloudfront 处理 SPA 的一种简单方法是使用 Lambda@Edge - 源请求(或 Cloudfront functions)。 目标是更改 Origin URI。

    一个我经常用于 SPA 的简单 js 代码(用于 v1.0.0 webapp):

    exports.handler = async (event) => {
       const request = event.Records[0].cf.request;
       const hasType = request.uri.split(/\#|\?/)[0].split('.').length >= 2;
       if (hasType) return request; // simply forward to the S3 object as it is an asset
       request.uri = '/v1.0.0/index.html'; // handle all react routes
       return request;
    };
    

    我检查 URL 中是否有扩展名(.png、.js、.css、...)。如果它是资产,我只需转发到 S3 对象,否则我发送 index.html。
    在这种情况下,为路径 /v1.0.0/my-react-router 发送 index.html。

    更新
    对于动态处理,您可以这样做(出于想法):
    request.uri = '/' + request.uri.split('/')[1] + '/index.html';

    或者更好的是,使用正则表达式解析 request.uri 以提取版本、资产的扩展名或 spa 路线。

    【讨论】:

    • 谢谢!这很有帮助。唯一的缺点是我似乎需要对版本进行硬编码?我将上传频繁的版本,理想情况下处理程序将能够动态路由到正确的版本
    • 路径中是否有每次版本?我可以更改动态路由处理的答案。
    • @NicholasHaley,我添加了一个示例来处理版本。您可以通过使用正则表达式解析一次路径来优化代码。
    • 很高兴确认(大部分)一切正常!唯一的问题是资产检查 hasType 不适用于我的特定 URL,因为版本号包含句点并创建误报
    猜你喜欢
    • 1970-01-01
    • 2012-02-26
    • 1970-01-01
    • 1970-01-01
    • 2018-12-01
    • 2021-05-14
    • 2021-08-10
    • 2022-07-21
    • 1970-01-01
    相关资源
    最近更新 更多