我有一个域example.com
。我有一个名为example.com
的S3存储桶,其中包含一个index.html
文件。现在,我想创建两个名为old
和new
的子文件夹,每个子文件夹包含单个页面应用程序的单独版本。请求https://example.com/old
(我想在浏览器的地址栏中输入请求时忽略index.html
)将打开index.html
子文件夹中的old
文件并请求https://example.com/new
会打开index.html
。执行这些重定向的最佳方法是什么?我应该在Route 53中设置一些内容example.com/old
- > example.com/old/index.html
还是有更好的方法吗?
答案 0 :(得分:12)
不需要lambda函数,这会增加项目的费用和复杂性。
以下答案引自https://stevepapa.com/
rdr[3].ToString("MM/dd/yyyy")
的工作方式应与https://stevepapa.com/my-great-new-post/
有一种巧妙的方法可以使这些流进入Cloudfront发行版,并且涉及将源原点从Cloudfront呈现给您的默认源更改。
选择原始来源时,Cloudfront将显示一个S3存储桶列表。
您无需从下拉列表中显示的存储桶中设置源,而是需要从其S3设置页面中获取该资源的静态网络托管端点,然后手动将其弹出。
使用Cloudfront分发源的静态源意味着对该分发的任何请求都将使用S3的根对象查找,并且您的404响应应在引用流过时消失。
重要: 完成此操作后,清除浏览器缓存和devalidate the items in your cloudfront distribution。否则,您所做的更改将不会立即生效。
答案 1 :(得分:4)
所以我昨晚也遇到了这个问题。
问题如下:
配置为网站存储桶时的S3是宽容的并且具有索引文档设置,设置为index.html
并且在根处应用,即,example.com
实际上被重定向到example.com/index.html
,并且它也会在子文件夹级别应用,因此example.com/new
或example.com/new/
都应重定向到example.com/new/index.html
,其中会有一个对象在桶中。 (如果没有,您将收到NoSuchKey
错误。)
然而,你那么"升级"您自己可以使用CloudFront,可能是HTTPS,这个功能就消失了。相反,CloudFront会对S3进行显式API调用,因此不会触发索引文档让步。它适用于root用户,但不适用于子文件夹。
RoutingRules
解决方案对我来说并不干净,因为通过指定KeyPrefixEquals
而非关键字恰好等于(不存在),我认为您无意中匹配。
我改为实现了一个Lambda @ Edge规则,该规则重写了CloudFront向S3发出的请求,以便在其中包含正确的键值。
从Lambda文档和A / B测试示例开始: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-examples.html#lambda-examples-general-examples
将代码更改为:
'use strict';
exports.handler = (event, context, callback) => {
/*
* Expand S3 request to have index.html if it ends in /
*/
const request = event.Records[0].cf.request;
if ((request.uri !== "/") /* Not the root object, which redirects properly */
&& (request.uri.endsWith("/") /* Folder with slash */
|| (request.uri.lastIndexOf(".") < request.uri.lastIndexOf("/")) /* Most likely a folder, it has no extension (heuristic) */
)) {
if (request.uri.endsWith("/"))
request.uri = request.uri.concat("index.html");
else
request.uri = request.uri.concat("/index.html");
}
callback(null, request);
};
并将其发布到您的CloudFront分配。
答案 2 :(得分:0)
Origin
,并将OriginPath
设为空(默认值为/
)您可以找到有用的演练here
问题:如果您的客户输入example.com
(没有old
/ new
)会怎样?
修改:2.
是可选的。您还可以将Route53 RecordSet链接到您的静态网站,但 CloudFront可让您通过https
(AWS Certificate Manager的帮助)为您的wesbite提供服务。
答案 3 :(得分:0)
您可以尝试设置重定向规则,这是一个未经测试的规则。
<RoutingRules>
<RoutingRule>
<Condition>
<KeyPrefixEquals>old</KeyPrefixEquals>
</Condition>
<Redirect>
<ReplaceKeyWith>old/index.html</ReplaceKeyWith>
</Redirect>
</RoutingRule>
<RoutingRule>
<Condition>
<KeyPrefixEquals>new</KeyPrefixEquals>
</Condition>
<Redirect>
<ReplaceKeyWith>new/index.html</ReplaceKeyWith>
</Redirect>
</RoutingRule>
</RoutingRules>
答案 4 :(得分:0)
使用HTML重定向文件可以更轻松地完成此操作
创建一个名为my-great-new-post的普通文件(不用担心不会与同一存储桶中的文件夹发生名称冲突)
在该文件中写一个元重定向代码(我在下面粘贴了代码)
将文件上传到根存储桶(my-great-new-post文件夹所在的位置)
修改新文件的元数据,并使Content-Type:text / html
在此放置文件的内容:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="refresh" content="0; url=/my-great-new-post/index.html">
</head>
<body>
</body>
</html>
答案 5 :(得分:0)
如果您正在使用CDK通过S3源创建CloudFrontWebDistribution,那么您的第一个猜测可能就是这样做:
OriginConfigs = new[] {
new SourceConfiguration {
S3OriginSource = new S3OriginConfig
{
S3BucketSource = bucket
}
Behaviors = new[] { new Behavior { IsDefaultBehavior = true } }
}
}
但是,要将Cloudfront配置为使用website-bucket-url(确实具有将目录解析为index.html的行为),则需要使用:
OriginConfigs = new[] {
new SourceConfiguration {
CustomOriginSource = new CustomOriginConfig
{
DomainName = bucket.BucketWebsiteDomainName,
OriginProtocolPolicy = OriginProtocolPolicy.HTTP_ONLY
},
Behaviors = new[] { new Behavior { IsDefaultBehavior = true } }
}
}
您需要将协议指定为HTTP_ONLY,因为网站存储桶不支持HTTPS。 CustomOriginSource的默认值为HTTPS_ONLY。
答案 6 :(得分:0)