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

Кэшированный конфликт не отвечает требованиям CORS с новым запросом CORS

Gist:

У меня есть страница, которая использует загрузку тега изображения из s3 (тег img HTML), и у меня есть страница, использующая xmlhttprequest. Загрузка тега кэшируется без заголовков CORS, и поэтому xmlhttprequest видит кэшированную версию, проверяет ее заголовки и терпит неудачу с ошибкой перекрестного происхождения.

Детали:

edit: Не работает как в сафари 5.1.6, так и в chrome 21.0.1180.89. Отлично работает в Firefox 14.

Используя S3 new CORS, я настрою a CORSRule так:

<CORSRule>
  <AllowedOrigin>*</AllowedOrigin>
  <AllowedMethod>GET</AllowedMethod>
  <AllowedMethod>HEAD</AllowedMethod>
  <MaxAgeSeconds>0</MaxAgeSeconds>
  <AllowedHeader>*</AllowedHeader>
</CORSRule>

Если я запрашиваю изображение с S3 без установки источника в заголовках запроса, я возвращаю изображение без заголовков CORS в ответе.

Получите кешированные и последующие запросы CORS (тот, который задает начало в заголовке запроса) отклоняются, поскольку браузер использует версию non CORS из кеша.

Какой лучший способ решить эту проблему? Могу ли я установить что-то, чтобы версия без CORS никогда не кэшировалась? Должен ли я дифференцировать запросы CORS, добавив ?some_flag к URL-адресу запроса?

В идеале у меня бы S3 ВСЕГДА отправляли обратно нужные заголовки CORS, даже если запрос не содержит "происхождение".

4b9b3361

Ответ 1

Я столкнулся с той же проблемой. Как сказал @monsur, проблема в том, что S3 не устанавливает заголовок "Vary: Origin", хотя это и должно быть. К сожалению, насколько я знаю, нет способа получить S3 для отправки этого заголовка. Тем не менее, вы можете обойти это, добавив параметр строки запроса к запросу, например ?origin=example.com, когда вам понадобится CORS. Строка запроса заставляет браузер не использовать кешированный ресурс.

В идеале, cloudfront и S3 отправили заголовок Vary: Origin, когда включен CORS, и/или Webkit будет неявно изменяться в заголовке Origin, который, как я полагаю, делает Firefox, поскольку у него нет этой проблемы.

Ответ 2

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

var img = document.createElement('img');
img.setAttribute('src', yourRequestUrl + '?d=' + Date.now());
tagToAppendImg.appendChild(img);

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

Ответ 3

Вы можете добавить тег img с помощью Javascript после запроса вашего CORS.

Ответ 4

Одним из решений было бы установить атрибут crossorigin='use-credentials' в img -tag, чтобы заставить браузер всегда выполнять запрос CORS, см. здесь: fooobar.com/questions/169812/...

Другим решением будет настройка вашего дистрибутива 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.

Ответ 5

Я столкнулся с этой проблемой. Я закончил создание облачного дистрибутива перед моим ведомым S3 и установил параметры Origin Custom Headers в разделе Origin Settings в облачном режиме, чтобы отправить Origin: https://example.com в исходное S3. Это приводит к тому, что S3 всегда обслуживает заголовки CORS, так как он всегда видит заголовок запроса Origin. Чтобы сделать это, вы должны убедиться, что заголовок Origin не включен в белый список каким-либо вашим поведением в облачном режиме.

tl; dr: Я сказал cloudfront отправлять Origin: https://example.com с каждым запросом в исходное S3 и обслуживал мой контент через облачную область.