Подтвердить что ты не робот

Как вы устанавливаете корневой объект по умолчанию для подкаталогов для статически размещенного веб-сайта в Cloudfront?

Как вы устанавливаете корневой объект по умолчанию для подкаталогов на статически размещенном веб-сайте в Cloudfront? В частности, я бы хотел, чтобы www.example.com/subdir/index.html обслуживался всякий раз, когда пользователь запрашивает www.example.com/subdir. Обратите внимание, что для доставки статического веб-сайта, содержащегося в ведре S3. Кроме того, я хотел бы использовать идентификатор доступа источника, чтобы ограничить доступ к ведро S3 только Cloudfront.

Теперь я знаю, что Cloudfront работает иначе, чем S3 и amazon states :

Поведение корневых объектов по умолчанию CloudFront отличается от поведения поведение индексных документов Amazon S3. Когда вы настраиваете Amazon S3 ведро в качестве веб-сайта и указать индексный документ, возвращается Amazon S3 индексный документ, даже если пользователь запрашивает подкаталог в ведро. (Копия индексного документа должна появляться в каждом подкаталог.) Дополнительные сведения о настройке Amazon S3 ведра в качестве веб-сайтов и об индексных документах, см. раздел "Хостинг" Веб-сайты в главе Amazon S3 в службе простого хранения Amazon Руководство разработчика.

Таким образом, даже несмотря на то, что Cloudfront позволяет нам указать объект root по умолчанию, это работает только для www.example.com, а не для www.example.com/subdir. Чтобы обойти эту проблему, мы можем изменить имя домена происхождения, чтобы указать конечную точку сайта, заданную S3. Это отлично работает и позволяет задавать корневые объекты равномерно. К сожалению, это не похоже на совместимость с идентификаторами доступа к подлинности. В частности, приведенные выше ссылки указывают:

Переход в режим редактирования:

Веб-дистрибутивы. Перейдите на вкладку "Происхождения", щелкните источник, который хотите изменить, и нажмите "Изменить". Вы можете создавать только исходный доступ идентичность для истоков, для которых Origin Type является источником S3.

В принципе, чтобы установить правильный корневой объект по умолчанию, мы используем конечную точку сайта S3, а не сам веб-сайт. Это несовместимо с идентификацией доступа источника. Таким образом, мои вопросы сводятся к

  • Можно ли указать корневой объект по умолчанию для всех подкаталогов для статически размещенного веб-сайта в Cloudfront?

  • Возможно ли установить идентификатор доступа источника для контента, поданного из Cloudfront, где источником является конечная точка сайта S3, а не ведро S3?

4b9b3361

Ответ 1

ОБНОВЛЕНИЕ: Похоже, я был неправ! См. Ответ JBaczuk, который должен быть принятым ответом на эту тему.

К сожалению, ответ на оба вопроса - нет.

1. Можно ли указать корневой объект по умолчанию для всех подкаталогов для статически размещенного веб-сайта в Cloudfront?

Нет. Как указано в Документах AWS CloudFront...

... Если вы определяете объект root по умолчанию, запрос конечного пользователя для подкаталога вашего дистрибутива не возвращает корневой объект по умолчанию. Например, предположим, что index.html является вашим корневым объектом по умолчанию и что CloudFront получает запрос конечного пользователя для каталога установки в вашем дистрибутиве CloudFront:

http://d111111abcdef8.cloudfront.net/install/

CloudFront не будет возвращать корневой объект по умолчанию, даже если в каталоге установки появится копия index.html.

...

Поведение корневых объектов по умолчанию CloudFront отличается от поведения индексных документов Amazon S3. Когда вы настраиваете ведро Amazon S3 в качестве веб-сайта и указываете индексный документ, Amazon S3 возвращает индексный документ, даже если пользователь запрашивает подкаталог в ведре. (Копия индексного документа должна отображаться в каждом подкаталоге.)

2. Возможно ли установить идентификатор доступа источника для контента, поданного из Cloudfront, где источником является конечная точка сайта S3, а не ведро S3?

Не напрямую. Ваши варианты создания с CloudFront - это ведра S3 или ваш собственный сервер.

Это второй вариант, который открывает некоторые интересные возможности. Вероятно, это побеждает цель того, что вы пытаетесь сделать, но вы можете настроить свой собственный сервер, единственной задачей которого является сервер происхождения CloudFront.

Когда запрос приходит на http://d111111abcdef8.cloudfront.net/install/, CloudFront отправит этот запрос на ваш исходный сервер, запросив /install. Вы можете настроить исходный сервер, как хотите, в том числе для обслуживания index.html в этом случае.

Или вы могли бы написать небольшое веб-приложение, которое просто принимает этот вызов и получает его напрямую от S3.

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

Ответ 2

Там IS способ сделать это. Вместо того, чтобы указывать его на свое ведро, выбрав его в раскрывающемся списке (www.example.com.s3.amazonaws.com), укажите его в статическом домене вашего ведра (например, www.example.com.s3-website-us -west-2.amazonaws.com):

введите описание изображения здесь

Этот форум AWS

Ответ 3

Активация хоста S3 означает, что вам нужно открыть ведро в мир. В моем случае мне нужно было сохранить ведро частным и использовать функции идентификации подлинности доступа, чтобы ограничивать доступ только к Cloudfront. Как предположил @Juissi, функция Lambda может исправить перенаправления:

'use strict';

/**
 * Redirects URLs to default document. Examples:
 *
 * /blog            -> /blog/index.html
 * /blog/july/      -> /blog/july/index.html
 * /blog/header.png -> /blog/header.png
 *
 */

let defaultDocument = 'index.html';

exports.handler = (event, context, callback) => {
    const request = event.Records[0].cf.request;

    if(request.uri != "/") {
        let paths = request.uri.split('/');
        let lastPath = paths[paths.length - 1];
        let isFile = lastPath.split('.').length > 1;

        if(!isFile) {
            if(lastPath != "") {
                request.uri += "/";
            }

            request.uri += defaultDocument;
        }

        console.log(request.uri);
    }

    callback(null, request);
};

После публикации вашей функции перейдите к распределению облачных вычислений на консоли AWS. Перейдите в Behaviors, затем выберите Origin Request в Lambda Function Associations и, наконец, вставьте ARN в свою новую функцию.

Ответ 4

Есть еще один способ получить файл по умолчанию, который будет использоваться в подкаталоге, например example.com/subdir/. Вы можете (программно) сохранить файл с ключом subdir/ в ковше. Этот файл будет не отображаться в консоли управления S3, но он действительно существует, и CloudFront будет обслуживать его.

Ответ 5

Обходным решением проблемы является использование lambda @edge для переписывания запросов. Нужно просто настроить lambda для события запроса на просмотр CloudFront и переписать все, что заканчивается на "/", и не равно "/" с корневым документом по умолчанию, например index.html.

Ответ 6

Я знаю, что это старый вопрос, но я просто боролся с этим сам. В конечном итоге моя цель заключалась в том, чтобы установить файл по умолчанию в каталог, и больше иметь конечный результат файла, который был отправлен без .html в конце его

Я закончил удаление .html из имени файла и программно/вручную установил тип mime на text/html. Это не традиционный способ, но, похоже, он работает и удовлетворяет моим требованиям для хороших URL-адресов, не жертвуя преимуществами облачной информации. Установка типа mime вызывает раздражение, но небольшая цена для оплаты выгод, на мой взгляд.

Ответ 7

В блоге AWS есть "официальное" руководство, в котором рекомендуется настроить функцию Lambda @Edge, вызванную вашим дистрибутивом CloudFront:

Конечно, плохой пользовательский интерфейс должен ожидать, что пользователи всегда будут набирать index.html в конце каждого URL (или даже знают, что он должен быть там). До сих пор не было простого способа предоставить эти простые URL-адреса (эквивалентные Директиве DirectoryIndex в конфигурации веб-сервера Apache) пользователям через CloudFront. Нет, если вы все еще хотите ограничить доступ к источнику S3 с помощью OAI. Однако с выпуском Lambda @Edge вы можете использовать функцию JavaScript, выполняемую на пограничных узлах CloudFront, для поиска этих шаблонов и запроса соответствующего ключа объекта из источника S3.

Решение

В этом примере вы используете вычислительную мощность на краю CloudFront, чтобы проверить запрос как входящий от клиента. Затем перезапишите запрос, чтобы CloudFront запрашивал индексный объект по умолчанию (index.html в этом случае) для любого URI запроса, который заканчивается на '/.

Когда запрос делается против веб-сервера, клиент указывает объект, который будет получен в запросе. Вы можете использовать этот URI и применять к нему регулярное выражение, чтобы эти URI были разрешены к объекту индекса по умолчанию, прежде чем CloudFront запросит объект из источника. Используйте следующий код:

'use strict';
exports.handler = (event, context, callback) => {

    // Extract the request from the CloudFront event that is sent to [email protected]
    var request = event.Records[0].cf.request;

    // Extract the URI from the request
    var olduri = request.uri;

    // Match any '/' that occurs at the end of a URI. Replace it with a default index
    var newuri = olduri.replace(/\/$/, '\/index.html');

    // Log the URI as received by CloudFront and the new URI to be used to fetch from origin
    console.log("Old URI: " + olduri);
    console.log("New URI: " + newuri);

    // Replace the received URI with the URI that includes the index page
    request.uri = newuri;

    // Return to CloudFront
    return callback(null, request);

};

Следуйте приведенному выше руководству, чтобы увидеть все шаги, необходимые для его настройки, включая ведро S3, распределение CloudFront и создание функции Lambda @Edge.

Ответ 8

Другой альтернативой использованию lambda @edge является использование страниц ошибок CloudFront. Настройте пользовательский ответ об ошибке, чтобы отправить все 403 в определенный файл. Затем добавьте javascript в этот файл, чтобы добавить index.html к URL-адресам, которые заканчиваются на /. Образец кода:

if ((window.location.href.endsWith("/") && !window.location.href.endsWith(".com/"))) {
    window.location.href = window.location.href + "index.html";
}
else {
    document.write("<Your 403 error message here>");
}