Одностраничное приложение с Lambda@Edge

Итак, у меня есть SPA, обслуживаемый AWS S3 AWS Cloudfront. Я настроил следующее поведение страниц ошибок:

404: Not Found -> /index.html с HTTP-кодом 200

Это необходимо, чтобы иметь возможность обрабатывать маршрутизацию на стороне клиента.

Теперь у меня есть функция Lambda@Edge, которая запускается viewer-response событие в Cloudfront и устанавливает некоторые пользовательские заголовки, такие как HSTS и X-Frame. Функция вызывается и работает, как и предполагалось, на всех ресурсах, кроме фактического /index.html, Я склонен думать, что это потому, что он обрабатывается вышеупомянутым поведением страниц ошибок в Cloudfront, так как фактический запрос GET для html обрабатывается конфигурацией страниц ошибок в Cloudfront.

Каков практический подход к решению этой проблемы?

Я не уверен, почему перенаправление не вызывает лямбда-функцию. Есть ли способ реализовать ту же логику, что и конфигурация страниц ошибок в lambda@edge?

1 ответ

Решение

обновление: поведение службы изменилось.

https://aws.amazon.com/about-aws/whats-new/2017/12/lambda-at-edge-now-allows-you-to-customize-error-responses-from-your-origin/

Приведенный ниже ответ был верным на момент публикации, но больше не применим. Исходные ошибки теперь вызывают функцию Lambda@Edge, как и ожидалось в триггерах исходного ответа (но не в триггерах ответа зрителя).

Обратите внимание, что вы можете сгенерировать собственное тело ответа в триггере исходного ответа, но у вас нет программного доступа для чтения исходного тела ответа, возвращенного из источника, если оно есть. Вы можете заменить его или оставить все как есть - каким бы он ни был. Это связано с тем, что триггеры Lambda@Edge Origin Response не ждут срабатывания после того, как CloudFront получит полный ответ от источника - они, похоже, срабатывают, как только источник заканчивает возвращать полные, действительные заголовки ответа обратно в CloudFront.

Когда вы работаете с HTTP-ответом, обратите внимание, что Lambda@Edge не предоставляет тело HTML, возвращаемое исходным сервером, триггеру origin-response. Вы можете сгенерировать тело статического содержимого, установив для него желаемое значение, или удалить тело внутри функции, установив пустое значение. Если вы не обновите поле тела в своей функции, исходное тело, возвращаемое сервером происхождения, возвращается обратно в средство просмотра.

https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-updating-http-responses.html

Важные напоминания: всякий раз, когда вы тестируете изменения на CloudFront, помните, что ваши изменения начинают работать быстрее, чем вы ожидаете, прежде чем состояние распространения изменится на Deployed, но вам может потребоваться сделать недействительной кэш-память, чтобы сделать ваши изменения полностью живыми и видимыми. Инвалидация должна включать путь, фактически запрашиваемый браузером, а не путь, запрашиваемый у источника (если отличается), или /* сделать все недействительным. При просмотре ответа из CloudFront, если есть Age: заголовок ответа, вы просматриваете кэшированный ответ. Помните также, что ошибки используют другой набор таймеров для кэширования ответов. Они настраиваются отдельно от значений TTL в поведении кэша. См. Мой ответ на Amazon CloudFront Latency для объяснения того, как изменить минимальный TTL кэширования ошибок, который по умолчанию равен 5 минутам и в целом не учитывает Cache-Control заголовки. Это защитная мера для предотвращения чрезмерных ошибок до вашего источника (или запуска ваших функций Lambda), но сбивает с толку во время тестирования и устранения неполадок, если вы не знаете о его влиянии.


(оригинальный ответ следует)

CloudFront не выполняет лямбда-функции для ответа источника и событий ответа средства просмотра, если источник возвращает код состояния HTTP 400 или выше.

http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-requirements-limits.html

Это означает, что необработанная ошибка не приводит к срабатыванию ответа.

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

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

Фактически, кажется, что триггер Origin Response имеет больше смысла для вашего приложения в любом случае, потому что он сможет изменить ответ до того, как он попадет в кэш, и добавленные заголовки будут кэшированы вместе с ответом - что должно привести к в общем уменьшении количества срабатываний триггера.

Вы можете добавить его в качестве триггера Origin Response, подождать, пока распределение вернется к Deployed, а затем сделать недействительным кеш для /* (чтобы вы не обслуживали страницы, которые были кэшированы без добавления заголовков), а после завершения аннулирования удалите триггер Viewer Response.

Кроме того: я отправил запрос функции для поддержки триггеров ответа при возникновении ошибок, но я не знаю, планируют ли они это добавить или нет, и, очевидно, я был не единственным, так как функция была реализована и выпущена, так как описано в пересмотренном ответе.

Другие вопросы по тегам