如何在子文件夹中进行S3 + Cloudfrond + 2 SPA反应应用程序?



我想使用 S3 + Cloudfront 在子文件夹中提供 2 个不同的反应应用程序

myapp.com/app-one/<-这是index.html
myapp.com/app-two/<-这是另一个index.html

我知道如何配置创建-反应-应用程序和反应路由器来处理这个问题。
https://create-react-app.dev/docs/deployment/#building-for-relative-paths

问题在于配置 S3 + Cloudfront 来处理重定向。

当您在浏览器中输入 url 时:
myapp.com/app-one/some-route- 它应该重定向到 index.html ofapp-one
myapp.com/app-two/some-route- 它应该重定向到 index.html ofapp-two

不幸的是,S3 只允许您为Static website hosting定义一个回退file.html(404(

我也不想使用哈希路由器:https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/docs/api/HashRouter.md

我一直在为一个角度应用程序解决同样的问题,并找到了一些解决方案,但我发现最有用的解决方案是使用 Lambda@Edge 函数,这允许您将静态文件保存在 S3 存储桶中而无需打开静态托管。

唯一对我有用的Lambda@Edge配置是这个答案中的配置。这是代码:

var path = require('path');
exports.handler = (event, context, callback) => {
// Extract the request from the CloudFront event that is sent to Lambda@Edge
var request = event.Records[0].cf.request;
const parsedPath = path.parse(request.uri);
// If there is no extension present, attempt to rewrite url
if (parsedPath.ext === '') {
// Extract the URI from the request
var olduri = request.uri;
// Match any '/' that occurs at the end of a URI. Replace it with a default index
var newuri = olduri.replace(/second-app.*/, 'second-app/index.html');
// Replace the received URI with the URI that includes the index page
request.uri = newuri;
}
// If an extension was not present, we are trying to load static access, so allow the request to proceed
// Return to CloudFront
return callback(null, request);
};

它基本上所做的是匹配子文件夹的 uri 并将所有请求重定向到正确的index.html文件。如果您有多个子文件夹,您可以简单地添加一些条件:

var path = require('path');
exports.handler = (event, context, callback) => {
// Extract the request from the CloudFront event that is sent to Lambda@Edge
var request = event.Records[0].cf.request;
const parsedPath = path.parse(request.uri);
// If there is no extension present, attempt to rewrite url
if (parsedPath.ext === '') {
// Extract the URI from the request
var olduri = request.uri;
var newuri = olduri
// Match any '/' that occurs at the end of a URI. Replace it with a default index
if(olduri.match(/first-sub-app.*/)){
newuri = olduri.replace(/first-sub-app.*/, 'first-sub-app/index.html');
} else if(olduri.match(/second-sub-app.*/)){
newuri = olduri.replace(/second-sub-app.*/, 'second-sub-app/index.html');
}
// Replace the received URI with the URI that includes the index page
request.uri = newuri;
}
// If an extension was not present, we are trying to load static access, so allow the request to proceed
// Return to CloudFront
return callback(null, request);
};

检查原始答案以获取有关设置的进一步说明以及有关其工作原理的更多详细信息,但它基本上忽略任何带有扩展名的请求,并且仅在与特定子目录匹配时才重定向。

最新更新