Назад | Перейти на главную страницу

Настройка Access-Control-Allow-Origin в Cloudfront

У меня возникают проблемы с отправкой статических ресурсов в Firefox с помощью AWS Cloudfront.

Chrome работает отлично, но Firefox возвращает ошибку CORS.

Если я выполняю curl, я получаю:

HTTP/1.1 200 OK
Content-Type: application/x-font-opentype
Content-Length: 39420
Connection: keep-alive
Date: Mon, 11 Aug 2014 21:53:50 GMT
Cache-Control: public, max-age=31557600
Expires: Sun, 09 Aug 2015 01:28:02 GMT
Last-Modified: Fri, 08 Aug 2014 19:28:05 GMT
ETag: "9df744bdf9372cf4cff87bb3e2d68fc8"
Accept-Ranges: bytes
Server: AmazonS3
Age: 2743
X-Cache: Hit from cloudfront
Via: 1.1 c445b20dfbf3128d810e975e5d84e2cd.cloudfront.net (CloudFront)
X-Amz-Cf-Id: ...

Как мне кажется, нужен заголовок:

Access-Control-Allow-Origin: *

Может кто-нибудь помочь мне? Почему это проблема Firefox, а не Chrome? Как я могу это решить?

Во-первых, вам нужно убедиться, что вы добавили заголовок источника в белый список:

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

http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/RequestAndResponseBehaviorCustomOrigin.html#request-custom-cors

Также см: http://aws.amazon.com/blogs/aws/enhanced-cloudfront-customization/

Кстати, по serverfault / stackoverflow есть несколько похожих вопросов и много ответов.

Это немного сложнее, чем указывает принятый ответ.

Поддержка CORS при использовании Cloudfront + S3 фактически реализована в S3, и, согласно Amazon, она работает следующим образом:

Заголовок Origin запроса должен соответствовать элементу AllowedOrigin.

Метод запроса (например, GET или PUT) или заголовок Access-Control Request-Method в случае, если предварительный запрос OPTIONS должен быть одним из элементов AllowedMethod.

Каждый заголовок, указанный в заголовке запроса Access-Control-Request-Headers в предварительном запросе, должен соответствовать элементу AllowedHeader.

Это имеет смысл, но может быть неясно, что если клиент не отправляет заголовок Origin, то эта обработка вообще не выполняется. И мы используем Cloudfront, который, если вы просто размещаете статические ресурсы, вы, вероятно, настроили его так, чтобы игнорировать все заголовки при кэшировании. Поэтому, если первый запрос к каждому файлу от определенного пограничного узла не включает заголовок Origin, он кэширует ответ без заголовка Access-Control-Allow-Origin.

В результате первый входящий запрос будет определять, какие заголовки будут возвращены для всех запросов, пока не истечет срок действия кеша.

Есть несколько способов исправить это.

  • Настройте Cloudfront для условного кэширования на основе заголовка «Источник».

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

  • Используйте Lambda @ edge для принудительной установки заголовков, это можно сделать только один раз для каждого запроса источника (S3).

Полностью гибкий, но увеличивает накладные расходы и стоимость.

  • Сделайте так, чтобы облачный интерфейс заменял заголовок «Origin» фиктивным значением для каждого запроса.

Это действительно полезно только в случае «Access-Control-Allow-Origin: *», и это немного похоже на взлом, но, вероятно, это лучшее текущее решение при размещении статических ресурсов на cloudfront + S3.