Правильная конфигурация SOS + Cloudfront CORS?
Мое приложение хранит изображения на S3, а затем проксирует их через Cloudfront. Я рад использовать новую поддержку SOS CORS, чтобы использовать методы холста HTML5 (которые имеют политику перекрестного происхождения), но не могут правильно настроить мои S3 и Cloudfront. При попытке конвертировать изображение в элемент холста все еще запутывается в "Неуправляемая ошибка: SECURITY_ERR: DOM Exception 18".
Вот что я до сих пор:
S3
<CORSConfiguration>
<CORSRule>
<AllowedOrigin>MY_WEBSITE_URL</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
<CORSRule>
<AllowedOrigin>MY_CLOUDFRONT_URL</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
CloudFront
Происхождение
Origin Protocol Policy: Match Viewer
HTTP Port: 80
HTTPS Port: 443
Поведения
Origin: MY_WEBSITE_URL
Object Caching: Use Origin Cache Headers
Forward Cookies: None
Forward Query Strings: Yes
Есть ли что-то, что мне не хватает здесь?
ОБНОВЛЕНИЕ:
Просто попробовал изменить заголовки на
<AllowedHeader>Content-*</AllowedHeader>
<AllowedHeader>Host</AllowedHeader>
на основе этого вопроса Amazon S3 CORS (совместное использование ресурсов Cross-Origin) и загрузка междоменных шрифтов Firefox
По-прежнему нет.
ОБНОВЛЕНИЕ: БОЛЬШЕ ИНФОРМАЦИИ ПО ЗАПРОСУ
Request
URL:https://d1r5nr1emc2xy5.cloudfront.net/uploaded/BAhbBlsHOgZmSSImMjAxMi8wOS8xMC8xOC81NC80Mi85NC9ncmFzczMuanBnBjoGRVQ/32c0cee8
Request Method:GET
Status Code:200 OK (from cache)
ОБНОВЛЕНИЕ
Я думаю, может быть, моя просьба была неправильной, поэтому я попытался включить CORS с
img.crossOrigin = '';
но тогда изображение не загружается, и я получаю сообщение об ошибке: загрузка изображения с использованием кросс-оригинала, запрещенная политикой совместного использования ресурсов Cross-Origin.
Ответы
Ответ 1
26 июня 2014 года AWS выпустила корректное поведение Vary: Origin в CloudFront, так что теперь вы просто
-
Установите конфигурацию CORS для вашей корзины S3, включая
<AllowedOrigin>*</AllowedOrigin>
-
В CloudFront → Распределение → Поведения для этого источника
- Разрешенные методы HTTP: +OPTIONS
- Методы кэширования HTTP +OPTIONS
- Cache на основе выбранных заголовков запроса: белый список
Origin
заголовок.
-
Подождите ~ 20 минут, пока CloudFront распространит новое правило
Теперь ваш дистрибутив CloudFront должен кэшировать разные ответы (с соответствующими заголовками CORS) для разных клиентских заголовков Origin.
Ответ 2
Чтобы дополнить ответ @Brett. Есть страницы документации AWS, подробно описывающие CORS на CloudFront и CORS на S3.
Шаги подробно описаны ниже:
- В вашем S3 ведро перейдите в Разрешения → Конфигурация CORS
- Добавьте правила для CORS в редакторе,
<AllowedOrigin>
правило <AllowedOrigin>
. Сохраните конфигурацию. ![enter image description here]()
- В вашем дистрибутиве CloudFront перейдите к Поведение → выберите поведение → Изменить
- В зависимости от того, хотите ли вы кэшировать ответы
OPTIONS
или нет, согласно AWS, есть два пути:
- Если вы хотите, чтобы ответы OPTIONS кэшировались, сделайте следующее:
- Выберите параметры для параметров поведения кэша по умолчанию, которые включают кэширование для ответов OPTIONS.
- Сконфигурируйте CloudFront для пересылки следующих заголовков: Origin, Access-Control-Request-Headers и Access-Control-Request-Method.
- Если вы не хотите, чтобы ответы OPTIONS кэшировались, настройте CloudFront для пересылки заголовка Origin вместе с любыми другими заголовками, требуемыми вашим источником
![enter image description here]()
И с этим CORS из CloudFront с S3 должен работать.
Ответ 3
UPDATE: это уже не так с недавними изменениями в CloudFront. Yippee! См. Другие ответы для деталей. Я оставляю это здесь для контекста/истории.
Проблема
CloudFront не поддерживает CORS 100%. Проблема в том, как CloudFront кэширует ответ на запрос. Любой другой запрос для того же URL-адреса после этого приведет к кэшированному запросу независимо от источника. Ключевой частью этого является то, что он включает заголовки ответов из источника.
Первый запрос перед тем, как CloudFront имеет кеширование из Origin: http://example.com
, имеет заголовок ответа:
Access-Control-Allow-Origin: http://example.com
Второй запрос от Origin: https://example.com
(обратите внимание, что это HTTPS, а не HTTP) также имеет заголовок ответа:
Access-Control-Allow-Origin: http://example.com
Это то, что CloudFront кэшировал для URL. Это неверно - консоль браузера (по крайней мере, в Chrome) покажет сообщение о нарушении CORS, и все сломается.
Обход
Предлагаемая работа заключается в использовании разных URL-адресов для разных источников. Хитрость заключается в том, чтобы добавить уникальную строку запроса, которая отличается от другой, так что есть одна кэшированная запись для каждого источника.
Таким образом, наши URL-адреса будут выглядеть примерно так:
http://.../some.png?http_mysite.com
https://.../some.png?https_mysite.com
Этот вид работ, но каждый может заставить ваш сайт работать плохо, заменяя querystrings. Это возможно? Вероятно, не отладка этой проблемы - это огромная проблема.
Правильное обходное решение - не использовать CloudFront с CORS, пока они полностью не поддерживают CORS.
На практике
Если вы используете CloudFront для CORS, обратитесь к другому методу, который будет работать, когда CORS не будет. Это не всегда вариант, но сейчас я динамически загружаю шрифты с помощью JavaScript. Если запрос CORS для CloudFront завершился неудачно, я возвращаюсь к серверному прокси к шрифтам (а не к перекрестному происхождению). Таким образом, все работает, даже несмотря на то, что CloudFront каким-то образом получил плохую кэшированную запись для шрифта.
Ответ 4
Не совсем уверен в вашей проблеме:
https://forums.aws.amazon.com/thread.jspa?messageID=377513
ответил на некоторые из моих проблем с CORS, S3 и Cloudfront.
Я также обнаружил, что некоторые активы в ведре возвращаются с правильными заголовками CORS, а некоторые - нет. После недействительности активов все они вернулись с правильными заголовками, не уверены, почему некоторые из них нуждаются в недействительности, а другие - нет, поскольку они были загружены в одно и то же время в одном и том же типе: (