[英]Redirect to index.html for S3 subfolder
我有一個域example.com
。 我有一個名為example.com
的 S3 存儲桶設置,其中包含一個可用的index.html
文件。 現在我想創建兩個名為old
和new
的子文件夾,每個子文件夾包含一個單獨版本的單頁應用程序。 請求https://example.com/old
(我喜歡在瀏覽器的地址欄中輸入請求時省略index.html
)將打開old
子文件夾中的index.html
文件並請求https://example.com/new
將打開index.html
。 執行這些重定向的最佳方法是什么? 我應該在 Route 53 example.com/old
-> example.com/old/index.html
中設置一些東西還是有更好的方法?
不需要 lambda 函數來增加項目的費用和復雜性。
以下答案引用自https://stevepapa.com/
https://stevepapa.com/my-great-new-post/
預計將以與以下方式相同的方式工作:https://stevepapa.com/my-great-new-post/index.html
有一個聰明的小方法可以讓這些流向 Cloudfront 分發,它涉及更改 Cloudfront 默認顯示給您的來源。
選擇原始來源時,Cloudfront 將向您顯示 S3 存儲桶列表。
您無需從下拉列表中顯示的存儲桶中設置源,而是需要從其 S3 設置頁面中獲取該資源的靜態 Web 托管端點並手動將其彈出。
對 Cloudfront 分發源使用靜態源意味着對該分發的任何請求都將使用 S3 的根對象查找,並且您的 404 響應應該隨着引用流過而消失。
這樣做之后:
否則,您所做的更改不會立即生效。
所以我昨晚也遇到了這個問題。
問題如下:當配置為網站存儲桶時,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 調用,因此不會觸發索引文檔讓步。 它確實適用於根目錄,但不適用於子文件夾。
RoutingRules
解決方案在我看來並不干凈,因為通過指定KeyPrefixEquals
而不是 key exactly equals(不存在)我認為你會得到意想不到的匹配。
相反,我實施了一個 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 發行版。
使用 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>
如果您使用的是 CloudFront,則可以使用CloudFront 函數來創建簡單的重定向。
我修改了@jkingok 的解決方案。
function handler(event) {
var request = event.request;
if (request.uri !== "/" && (request.uri.endsWith("/") || request.uri.lastIndexOf(".") < request.uri.lastIndexOf("/"))) {
if (request.uri.endsWith("/")) {
request.uri = request.uri.concat("index.html");
} else {
request.uri = request.uri.concat("/index.html");
}
}
return request;
}
函數完成后,您可以通過轉到分配的“行為”選項卡來使用該函數,選擇要修改的路徑模式,然后在“函數關聯”下,對於查看器請求,選擇“CloudFront 函數”作為函數類型,然后在下拉列表中選擇您創建的函數。
保存行為后,您可以測試您的網站。
注意:此解決方案將不帶擴展名的每個 URL 重定向到“URL/index.html”,您可以將函數的行為修改為適合您的方式。
Origin
並將OriginPath
留空(默認值: /
)您可以在此處找到有用的演練
問題:如果您的客戶輸入example.com
(沒有old
/ new
)會發生什么?
編輯: 2.
是可選的。 您還可以將您的 Route53 RecordSet 鏈接到您的靜態網站,但CloudFront 使您能夠使用https
(借助AWS Certificate Manager )為您的網站提供服務。
如果您使用 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。
您可以嘗試設置重定向規則,這是一個未經測試的規則。
<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>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.