简体   繁体   English

具有多个基于路径的单页应用程序的 S3 / Cloudfront 客户端路由

[英]Client-side routing for S3 / Cloudfront with multiple path-based Single Page Apps

I have the following situation:我有以下情况:

  • An S3 bucket with multiple path-based applications, grouped by version number.具有多个基于路径的应用程序的 S3 存储桶,按版本号分组。 Simplified example:简化示例:
/v1.0.0
  index.html
  main.js
/v1.1.0
  index.html
  main.js
  • Each application is a (React) SPA and requires client-side routing (via React router)每个应用程序都是一个(React)SPA,并且需要客户端路由(通过 React 路由器)

I am using S3 with Cloudfront and have everything mostly working, however the client-side routing is broken.我正在将 S3 与 Cloudfront 一起使用,并且一切正常,但是客户端路由已损坏。 This is to say I am able to visit the root of each application, ie.这就是说我能够访问每个应用程序的根目录,即。 https://<app>.cloudfront.net/<version> , but cannot reach any client-side routes. https://<app>.cloudfront.net/<version> ,但无法到达任何客户端路由。

I'm aware that an error document can be set to redirect to an index.html , but I believe this solution only works when there is one index.html per bucket (ie. I cannot set an error document per route-based path).我知道可以将错误文档设置为重定向到index.html ,但我相信此解决方案仅在每个存储桶有一个index.html时才有效(即,我无法为每个基于路由的路径设置错误文档) .

What's the best way to get around this issue?解决此问题的最佳方法是什么?

One simple way to deal with SPA through Cloudfront is by using Lambda@Edge - Origin request (or Cloudfront functions ).通过 Cloudfront 处理 SPA 的一种简单方法是使用 Lambda@Edge - Origin 请求(或Cloudfront 函数)。 The objective is to change the Origin URI.目标是更改 Origin URI。

A simple js code that I use very often for SPAs (for the v1.0.0 webapp):我经常用于 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;
};

I check if there is an extension (.png, .js, .css, ...) in the URL.我检查 URL 中是否有扩展名(.png、.js、.css、...)。 If it is an asset, I simply forward to the S3 object otherwise I send the index.html.如果它是资产,我只需转发到 S3 object 否则我发送 index.html。
In that case, index.html is sent for the path /v1.0.0/my-react-router.在这种情况下,为路径 /v1.0.0/my-react-router 发送 index.html。

Updated更新
For dynamic handling, you can do like this (for the idea):对于动态处理,你可以这样做(为了这个想法):
request.uri = '/' + request.uri.split('/')[1] + '/index.html';

Or even better, use regexp to parse the request.uri in order to extract the version, the asset's extension or the spa route.或者更好的是,使用正则表达式解析request.uri以提取版本、资产的扩展名或 spa 路线。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Kubernetes nginx HTTPS 在 AWS 中的基于入口路径的路由 - Kubernetes nginx ingress path-based routing of HTTPS in AWS 可以使用 Route53 进行基于路径的路由吗 - Can possible Path-Based routing with Route53 使用客户端加密的AWS S3数据保护 - AWS S3 Data Protection Using Client-Side Encryption 从客户端下载 AWS S3 文件 - AWS S3 File Download from the client-side AWS ALB 创建基于路径的路由 - 将子目录重定向到根目录 - AWS ALB Create Path-Based Routing - Redirect subdirectory to root 多个SPA的S3和CloudFront网站托管根据URL路径重定向到不同的index.html - S3 and CloudFront website hosting for multiple SPA redirect to different index.html based by url path 无法在单个 Cloudfront Distribution 上为多个 S3 存储桶提供服务 - Not able to server multiple S3 buckets on a single Cloudfront Distribution AWS服务器端TemporaryCredentials是否可用于客户端S3上传? - Are AWS server-side TemporaryCredentials usable for client-side S3 upload? AWS ALB 同时使用基于路径和基于端口的路由 - AWS ALB using path-based and port-based routing at the same time xyz.cloudfront.net上的AWS CloudFront +单个S3存储桶+多个子域 - AWS CloudFront + single S3 bucket + multiple subdomains on xyz.cloudfront.net
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM