ドメインexample.com
を持っています。 example.com
という名前のS3バケットがあり、index.html
ファイルが機能しています。次に、old
およびnew
という2つのサブフォルダーを作成します。それぞれに、単一ページアプリケーションの個別のバージョンが含まれています。 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
に何かを設定する必要がありますか、それとももっと良い方法がありますか?
プロジェクトに費用と複雑さを追加するラムダ関数は必要ありません。
次の回答は https://stevepapa.com/ から引用されています
https://stevepapa.com/my-great-new-post/
は以下と同じように機能することが期待されます:https://stevepapa.com/my-great-new-post/index.html
これらをCloudfrontディストリビューションに流すための賢い小さな方法があり、Cloud Originがデフォルトで提示するものからソースOriginを変更する必要があります。
Originのソースを選択すると、CloudfrontはS3バケットのリストを表示します。
ドロップダウンリストに表示されるバケットからソースを設定する代わりに、S3設定ページからそのリソースの静的ウェブホスティングエンドポイントを取得し、手動でポップインする必要があります。
CloudfrontディストリビューションOriginに静的ソースを使用するということは、そのディストリビューションへのすべてのリクエストがS3のルートオブジェクトルックアップを使用することを意味し、参照が通過するにつれて404レスポンスが消えるはずです。
重要:これを行った後、ブラウザーのキャッシュをクリアし、 cloudfrontディストリビューションのアイテムを無効化 します。そうしないと、行った変更がすぐに反映されません。
だから昨夜もこの問題がありました。
問題は次のとおりです。Webサイトバケットとして構成されているS3が許容範囲であり、インデックスドキュメント設定が_index.html
_に設定されている場合、これはルートで適用されます。つまり、_example.com
_は実際に_example.com/index.html
_であり、サブフォルダレベルでも適用されるため、_example.com/new
_または_example.com/new/
_の両方が_example.com/new/index.html
_にリダイレクトされ、バケット内にオブジェクトが存在します。 (そうでない場合は、代わりにNoSuchKey
エラーが表示されます。)
ただし、HTTPSのように、自分でCloudFrontに「アップグレード」すると、この機能はなくなります。 CloudFrontは代わりにS3への明示的なAPI呼び出しを行うため、インデックスドキュメントの譲歩はトリガーされません。ルートに対しては機能しますが、サブフォルダに対しては機能しません。
RoutingRules
ソリューションは、キーと完全に等しい(存在しない)ではなくKeyPrefixEquals
を指定すると、意図しない一致が発生するため、見た目がきれいではありません。
代わりに、CloudFrontがS3に対して行うリクエストを書き換えて適切なキー値を設定するLambda @ Edgeルールを実装しました。
こちらの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>
リダイレクトルールの設定を試すことができます。これはテストされていないルールです。
<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>
Origin
として設定し、OriginPath
を空のままにします(デフォルト:/
)役立つチュートリアルが こちら にあります
質問:顧客がexample.com
(old
/new
なし)を入力するとどうなりますか?
編集:2.
はオプションです。 Route53 RecordSetを静的ウェブサイトにリンクすることもできますbutCloudFrontを使用すると、https
( AWS Certificate Manager )。