我有两个静态网络应用程序(create-react-apps),目前在两个独立的S3存储桶中。两个存储桶都配置为公共读取+静态Web托管,访问其S3托管URL正确显示网站。
Bucket 1 - First App:
index.html
static/js/main.js
Bucket 2 - Second App:
/secondapp/
index.html
static/js/main.js
我为此设置了一个Cloudfront - 默认的cloudfront origin正确加载FirstApp
,这样www.mywebsite.com默认加载index.html。
对于SecondApp
,我设置了一个缓存行为,以便路径模式secondapp/*
指向SecondApp存储桶URL。
在我的浏览器中,当我访问www.mywebsite.com/secondapp/
时,它正确显示第二个Web应用程序。
但是,如果我省略了尾部斜杠,我会看到第一个应用程序,这是不受欢迎的。如果我访问www.mywebsite.com/secondapp/something
,我也会看到第一个应用程序,这也是不受欢迎的。 (我希望它加载secondapp
的.html)
这两个应用程序都配置为通过react-router-dom使用html5推送状态。
我希望的行为是访问以下内容显示正确的站点/存储桶:
www.mywebsite.com
- 目前正在工作
www.mywebsite.com/secondapp/
- 目前正在工作
www.mywebsite.com/secondapp
- (没有尾随斜线)不工作,显示First App
www.mywebsite.com/secondapp/something_else
- 不工作,显示First App
我怎样才能实现理想的行为?
谢谢!
在研究了这个问题后,我能够使用lambda @ edge(https://aws.amazon.com/lambda/edge/)解决它
通过部署一个简单的javascript函数将特定路径路由到所需的s3存储桶,我们能够实现类似nginx的路由设置。该函数位于我们的Cloudfront CDN上的lambda @ edge上,这意味着您可以指定何时触发它。对我们来说,它是在“原始请求”上
我的设置如下:
arn:aws:lambda:us-east-1:12345667890:function:my-function-name
)这是我使用的lambda函数的一个例子。
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);
};
这些是我用于此解决方案的资源: