S3 CORS, всегда отправлять Vary: Origin
Я использую ведро S3 за Cloudfront с включенным CORS. Если клиент делает запрос с заголовком Origin, то S3 (и облачный) отвечают заголовком "Vary: Origin", однако, если запрос выполнен без заголовка Origin, тогда ответ не содержит заголовок Vary.
Это проблематично, потому что я использую ресурс из облачного /s 3 в теге img, и в этом случае браузер делает запрос без заголовка Origin, а затем делает запрос ajax для указанного изображения. Затем браузер использует кэшированную версию изображения без заголовка Access-Control-Allow-Origin и поэтому отклоняет запрос.
Есть ли способ заставить S3 всегда возвращать заголовок "Vary: Origin"?
Ответы
Ответ 1
Другим решением будет настройка вашего дистрибутива CloudFront для автоматического обращения запросов Non-CORS в запросы CORS. Это можно сделать, добавив заголовок CORS для каждого запроса. CloudFront отправляет на S3, используя недавно добавленную функцию CloudFront "Заголовки заголовка элемента управления для заголовка".
См. объявление функции здесь: https://aws.amazon.com/blogs/aws/cloudfront-update-https-tls-v1-1v1-2-to-the-origin-addmodify-headers/
И документация здесь: http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/forward-custom-headers.html.
Ответ 2
Я сделал учетную запись, чтобы ответить на ваш вопрос, потому что для этой проблемы очень мало хороших ответов (и нескольких связанных).
Проблема, которую вы описываете, по какой-то причине в основном связана с хром, FF и IE, кажется, достаточно умна, чтобы не делиться кешем между AJAX и обычными вызовами в этих случаях.
Проблема
Давайте сначала опишем, почему проблема возникает для будущих читателей:
- Браузер (Chrome) запрашивает сервер, используя обычный тег
<img>
или <script>
. Если сервер находится в одном домене, он не содержит заголовки CORS.
- Сервер (S3) возвращает ресурс. Если в запросе отсутствует заголовок Origin, он не присоединяет заголовки CORS в ответе, поскольку они являются избыточными.
- Браузер (Chrome) попытается снова получить ресурс, используя AJAX, но на этот раз на самом деле не идет на сервер, а просматривает кешированный ресурс.
- Браузер (Chrome) В кеш-версии нет заголовков CORS. Он отбросит запрос как нарушение доступа-контроль-разрешение-происхождение или другие связанные с этим проблемы.
Решение
В HTML5 есть атрибут crossorigin
, который можно добавить в теги, чтобы указать, что им нужно отправить информацию о происхождении.
Возможные значения crossorigin='anonymous'
и crossorigin='use-credentials'
, они не имеют никакого отношения к заданному вопросу, но, как говорится в документации:
По умолчанию (то есть, когда атрибут не указан), CORS не используется вообще.
https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes
Итак, просто создайте теги изображений, подобные этому <img src='cloundfront.path' crossorigin='use-credentials'>
Вот оно. Это довольно неясно, поэтому я надеюсь, что этот ответ сэкономит время исследований кучам людей.