У меня есть домен example.com
. У меня есть ведро S3 с именем example.com
с файлом 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
или есть лучший способ сделать это?
Перенаправить в index.html для подпапки S3
Ответ 1
Нет необходимости в лямбда-функции, добавляющей затраты и сложность вашему проекту.
Следующий ответ цитируется с https://stevepapa.com/
Ожидается, что
https://stevepapa.com/my-great-new-post/
будет работать так же, как иhttps://stevepapa.com/my-great-new-post/index.html
Есть небольшой хитрый способ передать их в дистрибутив Cloudfront, и он включает в себя изменение источника источника по сравнению с тем, который Cloudfront предоставляет вам по умолчанию.
При выборе исходного источника Cloudfront покажет вам список сегментов S3.
Вместо того, чтобы устанавливать источник из корзины, показанной в раскрывающемся списке, вам нужно взять статическую конечную точку веб-хостинга для этого ресурса со страницы настроек S3 и вставить ее вручную.
Использование статического источника для источника распространения Cloudfront означает, что любой запрос к этому распределению будет использовать поиск корневого объекта S3s, и ваши 404 ответа должны исчезнуть по мере прохождения ссылок.
Важное замечание : После этого очистите кеш браузера и отмените проверку элементов в вашем облачном дистрибутиве. В противном случае внесенные вами изменения не вступят в силу немедленно.
Ответ 2
Поэтому у меня была и эта проблема прошлой ночью.
Проблема заключается в следующем: S3, когда он настроен как ведро веб-сайта, прощает и имеет параметр индексного документа, устанавливается в index.html
и это применяется к корню, т. example.com
фактически перенаправляется на example.com/index.html
, и он также применяется на уровне подпапки, поэтому example.com/new
или example.com/new/
должны быть перенаправлены на example.com/new/index.html
, где будет объект в ведре. (Если нет, вместо этого вы получите ошибку NoSuchKey
.)
Однако вы затем "обновляете" себя до CloudFront, вероятно, для HTTPS, и эта функция исчезает. CloudFront вместо этого делает явные вызовы API для S3 и, следовательно, не вызывает концессию индексного документа. Он работает для корня, но не для подпапок.
Решение 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.
Ответ 3
- Настройте свой Bucket для создания статического веб-сайта
- Создайте CloudFront Distribution: установите свое ведро как
Origin
и оставьте полеOriginPath
пустым (по умолчанию:/
) - Создайте запись Route53 RecordSet, которая ссылается на ваше распределение CloudFront
Вы можете найти полезное пошаговое руководство здесь
Вопрос: Что произойдет, если ваш клиент войдет в example.com
(без old
/new
)?
Изменение: 2.
является обязательным. Вы также можете связать свой Route53 RecordSet со своим статическим сайтом, но CloudFront позволяет вам обслуживать ваш wesbite с помощью https
(с помощью AWS Certificate Manager).
Ответ 4
Вы можете попробовать установить правила перенаправления. Это непроверенное правило.
<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>
Ответ 5
Есть еще более простой способ сделать это с помощью файла перенаправления 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>