[英]Client-side routing for S3 / Cloudfront with multiple path-based Single Page Apps
I have the following situation:我有以下情况:
/v1.0.0
index.html
main.js
/v1.1.0
index.html
main.js
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.