Перенаправить в index.html для подпапки S3

У меня есть домен 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/oldexample.com/old/index.html или есть лучший способ сделать это?

Ответ 1

Нет необходимости в лямбда-функции, добавляющей затраты и сложность вашему проекту.

Следующий ответ цитируется с https://stevepapa.com/

Ожидается, что https://stevepapa.com/my-great-new-post/ будет работать так же, как и https://stevepapa.com/my-great-new-post/index.html

Есть небольшой хитрый способ передать их в дистрибутив Cloudfront, и он включает в себя изменение источника источника по сравнению с тем, который Cloudfront предоставляет вам по умолчанию.

При выборе исходного источника Cloudfront покажет вам список сегментов S3. editing origin

Вместо того, чтобы устанавливать источник из корзины, показанной в раскрывающемся списке, вам нужно взять статическую конечную точку веб-хостинга для этого ресурса со страницы настроек S3 и вставить ее вручную. where the static hosting endpoint url is

Использование статического источника для источника распространения 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

  1. Настройте свой Bucket для создания статического веб-сайта
  2. Создайте CloudFront Distribution: установите свое ведро как Origin и оставьте поле OriginPath пустым (по умолчанию: /)
  3. Создайте запись 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

  1. Создайте простой файл с именем my-great-new-post (не волнуйтесь, не будет конфликта имен с папкой в том же контейнере)

  2. Написать код мета-перенаправления в этот файл (я вставил код ниже)

  3. загрузить файл в корневую корзину (где находится папка my-great-new-post)

  4. изменить метаданные нового файла и сделать 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>