Это немного сложнее, чем указывает принятый ответ.
Поддержка 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.
В результате первый входящий запрос будет определять, какие заголовки будут возвращены для всех запросов до истечения срока действия кэша.
Есть несколько способов исправить / обойти это.
- Настройте облачный фронт для выполнения условного кэширования на основе заголовка «Origin».
Это прекрасно работает, если вы ожидаете только несколько или один источник, но в противном случае ваш коэффициент кэширования может стать очень плохим.
- Используйте Lambda @ edge для принудительной установки заголовков, это можно сделать только один раз для каждого запроса источника (S3).
Полностью гибкий, но добавляет накладные расходы и стоимость.
- Заставьте cloudfront переопределить заголовок «Origin» для фиктивного значения для каждого запроса.
Это действительно полезно только в случае «Access-Control-Allow-Origin: *», и это немного хакерское решение, но, вероятно, это лучшее из существующих решений при размещении статических ресурсов в cloudfront + S3.