Amazon S3 CORS (общий доступ к ресурсам между источниками) и загрузка междоменных шрифтов Firefox

существует давняя проблема с Firefox, не загружающим шрифт из другого источника, чем текущая веб-страница. Обычно проблема возникает, когда шрифты подаются на CDNs.

различные решения были подняты в других вопросах:

CSS @font-face не работает с Firefox, но работает с Chrome и IE

с введением Amazon S3 CORS существует ли решение с использованием CORS для решения проблемы загрузки шрифтов в В Firefox?

edit: было бы здорово увидеть образец конфигурации S3 CORS.

edit2: я нашел рабочее решение, фактически не понимая, что он сделал. Если кто-то может предоставить более подробные объяснения о конфигурациях и фоновой магии, которая происходит при интерпретации конфигурации Amazon, это будет очень оценено, как и с nzifnab, который выставил награду за это.

12 ответов


Обновление 10 Сентября 2014:

вам больше не нужно делать какие-либо хаки строки запроса ниже, так как Cloudfront правильно поддерживает CORS сейчас. См.http://aws.amazon.com/blogs/aws/enhanced-cloudfront-customization/ и этот ответ для получения дополнительной информации:https://stackoverflow.com/a/25305915/308315


OK, Я, наконец, получил шрифты, работающие с использованием конфигурации ниже с небольшой настройкой из примеров в документация.

мои шрифты размещаются на S3, но выходят на cloudfront.

я не уверен, почему это работает, я думаю, наверное, что <AllowedMethod> GET и <AllowedHeader> это.

если кто-то опытный с Amazon S3 CORS config может пролить свет на это, это будет очень признательно.

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>https://mydomain.com</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>Content-*</AllowedHeader>
        <AllowedHeader>Host</AllowedHeader>
    </CORSRule>
    <CORSRule>
        <AllowedOrigin>https://*.mydomain.com</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>Content-*</AllowedHeader>
        <AllowedHeader>Host</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

edit:

некоторые разработчики сталкиваются с проблемами кэширования Cloudfront Access-Control-Allow-Origin заголовок. Этот вопрос был обращение сотрудников AWS по ссылке (https://forums.aws.amazon.com/thread.jspa?threadID=114646) ниже, прокомментировано @Jeff-Atwood.

из связанного потока рекомендуется в качестве обходного пути использовать Строку Запроса для различения вызовов из разных доменов. Я приведу здесь сокращенный пример.

используя curl чтобы проверить заголовки ответа:

Домен A: a.domain.com

curl -i -H "Origin: https://a.domain.com" http://hashhashhash.cloudfront.net/font.woff?https_a.domain.com

заголовки ответов из домена A:

Access-Control-Allow-Origin: https://a.domain.com
Access-Control-Allow-Methods: GET
Access-Control-Max-Age: 3000
Access-Control-Allow-Credentials: true
X-Cache: Miss from Cloudfront

домен B: b.domain.com

curl -i -H "Origin: http://b.domain.com" http://hashhashhash.cloudfront.net/font.woff?http_b.domain.com

заголовки ответов из домена B:

Access-Control-Allow-Origin: http://b.domain.com
Access-Control-Allow-Methods: GET
Access-Control-Max-Age: 3000
Access-Control-Allow-Credentials: true
X-Cache: Miss from Cloudfront

Вы заметите Access-Control-Allow-Origin вернул различные значения, которые прошли кэширование Cloudfront.


после некоторой настройки я, кажется, получил это для работы без взлома строки запроса. Больше информации здесь: http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/RequestAndResponseBehaviorS3Origin.html#RequestS3-cors

Я иду через всю мою установку, так что легко понять, что я сделал, надеюсь, это поможет другим.

Справочная Информация: Я использую приложение Rails, которое имеет драгоценный камень asset_sync для размещения активов на S3. Этот включает шрифты.

в консоли S3 я нажал на мое ведро, свойства и "изменить конфигурацию cors", здесь:CORS config button

внутри textarea у меня есть что-то вроде:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>https://*.example.com</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

затем в панели Cloudfront (https://console.aws.amazon.com/cloudfront/home) я создал дистрибутив, добавил источник, который указал на мое ведро S3 adding an origin

затем добавлено поведение для пути по умолчанию, чтобы указать на источник на основе S3 I установка. То, что я также сделал, это нажать на заголовки белого списка и добавить Origin: adding a behavior and whitelist headers

сейчас происходит следующее, что я считаю правильным:

1) Убедитесь, что заголовки S3 установлены правильно

curl -i -H "Origin: https://example.com" https://s3.amazonaws.com/xxxxxxxxx/assets/fonts/my-cool-font.ttf
HTTP/1.1 200 OK
x-amz-id-2: Ay63Qb5uR98ag47SRJ91+YALtc4onRu1JUJgMTU98Es/pzQ3ckmuWhzzbTgDTCt+
x-amz-request-id: F1FFE275C0FBE500
Date: Thu, 14 Aug 2014 09:39:40 GMT
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: GET
Access-Control-Max-Age: 3000
Access-Control-Allow-Credentials: true
Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method
Cache-Control: public, must-revalidate, proxy-revalidate, max-age=180
Last-Modified: Mon, 09 Dec 2013 14:29:04 GMT
ETag: "98918ee7f339c7534c34b9f5a448c3e2"
Accept-Ranges: bytes
Content-Type: application/x-font-ttf
Content-Length: 12156
Server: AmazonS3

2) Проверьте Cloudfront работает с заголовками

curl -i -H "Origin: https://example.com" https://xxxxx.cloudfront.net/assets/fonts/my-cool-font.ttf
HTTP/1.1 200 OK
Content-Type: application/x-font-ttf
Content-Length: 12156
Connection: keep-alive
Date: Thu, 14 Aug 2014 09:35:26 GMT
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: GET
Access-Control-Max-Age: 3000
Access-Control-Allow-Credentials: true
Cache-Control: public, must-revalidate, proxy-revalidate, max-age=180
Last-Modified: Mon, 09 Dec 2013 14:29:04 GMT
ETag: "98918ee7f339c7534c34b9f5a448c3e2"
Accept-Ranges: bytes
Server: AmazonS3
Vary: Origin
X-Cache: Miss from cloudfront
Via: 1.1 77bdacfea247b6cbe84dffa61da5a554.cloudfront.net (CloudFront)
X-Amz-Cf-Id: cmCxaUcFf3bT48zpPw0Q-vDDza0nZoWm9-_3qY5pJBhj64iTpkgMlg==

(обратите внимание, что выше был промах от cloudfront, потому что эти файлы кэшируются в течение 180 секунд, но то же самое работает над хитами)

3) Нажмите cloudfront с помощью другое происхождение (но то, которое разрешено на CORS для ведра S3) -Access-Control-Allow-Origin не кэшируется! ура!

curl -i -H "Origin: https://www2.example.com" https://xxxxx.cloudfront.net/assets/fonts/my-cool-font.ttf
HTTP/1.1 200 OK
Content-Type: application/x-font-ttf
Content-Length: 12156
Connection: keep-alive
Date: Thu, 14 Aug 2014 10:02:33 GMT
Access-Control-Allow-Origin: https://www2.example.com
Access-Control-Allow-Methods: GET
Access-Control-Max-Age: 3000
Access-Control-Allow-Credentials: true
Cache-Control: public, must-revalidate, proxy-revalidate, max-age=180
Last-Modified: Mon, 09 Dec 2013 14:29:04 GMT
ETag: "98918ee7f339c7534c34b9f5a448c3e2"
Accept-Ranges: bytes
Server: AmazonS3
Vary: Origin
X-Cache: Miss from cloudfront
Via: 1.1 ba7014bad8e9bf2ed075d09443dcc4f1.cloudfront.net (CloudFront)
X-Amz-Cf-Id: vy-UccJ094cjdbdT0tcKuil22XYwWdIECdBZ_5hqoTjr0tNH80NQPg==

обратите внимание, что домен успешно изменился без взлома строки запроса.

когда я меняю заголовок Origin, кажется, всегда есть X-Cache: Miss from cloudfront по первому запросу, а затем я получаю ожидаемое X-Cache: Hit from cloudfront

P.S. стоит отметить, что при выполнении curl-I (capital I) не будут отображаться заголовки Access-Control-Allow-Origin поскольку это только голова, я делаю-я делаю это, чтобы получить и прокрутить вверх.


мои шрифты обслуживались правильно до последнего нажатия на Heroku... Я не знаю почему, но подстановочный знак в CORS allowed origin перестал работать. Я добавил все мои prepro и pro домены к политике CORS в настройке ковша, поэтому теперь это выглядит так:

<CORSConfiguration>
    <CORSRule>
        <AllowedOrigin>http://prepro.examle.com</AllowedOrigin>
        <AllowedOrigin>https://prepro.examle.com</AllowedOrigin>
        <AllowedOrigin>http://examle.com</AllowedOrigin>
        <AllowedOrigin>https://examle.com</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>Authorization</AllowedHeader>
    </CORSRule>

</CORSConfiguration>

UPDATE: добавьте свой http://localhost:PORT слишком


ну, в документации говорится, что вы можете вставить конфигурацию как "подресурс cors в вашем ведре."Я понял это так, что я создам файл под названием "cors" в корне моего ведра с конфигурацией, но это не сработает. В конце концов мне пришлось войти в область администрирования Amazon S3 и добавить конфигурацию в properties диалог моего ведра.

S3 может использовать лучшую документацию...


в моем случае я не определил пространство имен XML и версию в конфигурации CORS. Определение этих работало.

изменить

<CORSConfiguration>

to

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">

есть лучший и простой способ!

Я лично предпочитаю использовать мои поддомены DNS для решения этой проблемы. Если мой CDN позади cdn.myawesomeapp.com вместо sdf73n7ssa.cloudfront.net тогда браузеры не будут freakout и блокировать их как проблемы безопасности кросс-домена.

чтобы указать поддомен на домен AWS Cloudfront, перейдите на панель управления AWS Cloudfront, выберите дистрибутив Cloudfront и введите поддомен CDN в альтернативный домен Поле имена (CNAMEs). Что-то вроде cdn.myawesomeapp.com сделаю.

теперь вы можете перейти к поставщику DNS (например, AWS Route 53) и создать CNAME для cdn.myawesomeapp.com указывая на sdf73n7ssa.cloudfront.net.

http://blog.cloud66.com/cross-origin-resource-sharing-cors-blocked-for-cloudfront-in-rails/


эта конфигурация работала на меня. Я могу перечислить объект, получить, обновить и удалить.

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  <CORSRule>
    <AllowedOrigin>http://localhost:3000</AllowedOrigin>
    <AllowedMethod>HEAD</AllowedMethod>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>PUT</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedMethod>DELETE</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
    <ExposeHeader>ETag</ExposeHeader>
    <ExposeHeader>x-amz-meta-custom-header</ExposeHeader>
  </CORSRule>
</CORSConfiguration>

<ifModule mod_headers.c>

   Header set Access-Control-Allow-Origin: http://domainurl.com

</ifModule>

Простое Решение


В Amazon S3 конфигурация CORS (S3 Bucket / Permissions / CORS) если вы используете это:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>

CORS хорошо работает для файлов Javascript и CSS, но Это не работает для файлов шрифтов.

вы должны указать домен, чтобы разрешить CORS, используя шаблон, выраженный в ответе @VKen:https://stackoverflow.com/a/25305915/618464

и:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
<CORSRule>
    <AllowedOrigin>https://*.mydomain.com</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

Не забудьте заменить". mydomain.com-для ваших владений.

после этого, аннулировать кэш CloudFront (CloudFront онлайн / инвалидизации / создать недействительности) и он будет работать.


перезапуск моего приложения spring boot (сервер) решил проблему для меня.

Я правильно настроил CORS на S3. Завиток давал правильный ответ с заголовком origin. Safari правильно выбирал шрифт. Это был только хром, который не хотел принимать CORS.

Не уверен, что именно вызвало поведение. Должно быть, что-то связано с If-modified-since


Да, конечно. Firefox поддерживает CORS для шрифтов, так же, как требует спецификация вhttp://dev.w3.org/csswg/css3-fonts/#allowing-cross-origin-font-loading


У меня была такая же проблема. Мне не нужно было добавлять CNAME в мой CDD, чтобы избежать междоменных проблем... Я просто должен был сделать следующее:

перейдите к свойствам ведра - > разрешения - > добавить дополнительные разрешения - > участник: все и проверьте опцию "список".

Это наглядный пример. http://i.stack.imgur.com/KOEwy.png

надеюсь, что это будет полезно для кого-то.