Amazon S3 CORS (Cross-Origin Resource Sharing) I Firefox cross-domain font loading

Istnieje od dawna problem z Firefoksem, który nie ładuje czcionek z innego źródła niż bieżąca strona internetowa. Zazwyczaj problem pojawia się, gdy czcionki są serwowane na CDN.

Różne rozwiązania zostały podniesione w innych pytaniach:

CSS @font-face nie działa z Firefoksem, ale działa z Chrome i IE

Wraz z wprowadzeniem Amazon S3 CORS, czy istnieje rozwiązanie wykorzystujące CORS do rozwiązania problemu ładowania czcionek w Firefoksie?

Edit: byłoby warto zobaczyć przykładową konfigurację S3 CORS.

Edit2: znalazłem rozwiązanie działające bez zrozumienia, co to robi. Jeśli ktoś mógłby dostarczyć bardziej szczegółowych wyjaśnień na temat configów i magii tła, która dzieje się na interpretacji konfiguracji Amazona, będzie to bardzo doceniane, jak w przypadku nzifnab, który postawił za to nagrodę.

Author: Community, 2012-09-01

12 answers

Aktualizacja 10 Września 2014:

Nie powinieneś już wykonywać żadnych hacków ciągów zapytań poniżej, ponieważ Cloudfront poprawnie obsługuje teraz CORS. Zobacz http://aws.amazon.com/blogs/aws/enhanced-cloudfront-customization/{[16] } a ta odpowiedź po więcej informacji: https://stackoverflow.com/a/25305915/308315


OK, w końcu uruchomiłem czcionki używając poniższej konfiguracji z odrobiną poprawek z przykładów w dokumentacji.

Moje czcionki to hosted on S3, ale fronted by cloudfront.

Nie jestem pewien, dlaczego to działa, domyślam się prawdopodobnie, że <AllowedMethod> GET oraz <AllowedHeader> Content-* jest potrzebny.

Jeśli ktoś biegły z konfiguracją Amazon S3 CORS może rzucić trochę światła na to, będzie to bardzo doceniane.

<?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:

Niektórzy programiści mają problemy z buforowaniem nagłówka Access-Control-Allow-Origin w chmurze. Problem ten został poruszony przez pracowników AWS w linku ( https://forums.aws.amazon.com/thread.jspa?threadID=114646 ) poniżej, skomentowane przez @ Jeff-Atwood.

Z połączonego wątku zaleca się, jako obejście, użycie ciągu zapytania do rozróżniania wywołań z różnych domen. Tutaj powtórzę skrócony przykład.

Użycie curl do sprawdzenia nagłówków odpowiedzi:

Domena a: a.domain.com

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

Nagłówki odpowiedzi z domeny 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

Domena B: b.domain.com

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

Nagłówki odpowiedzi z domeny 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

Zauważysz, że Access-Control-Allow-Origin zwróciło różne wartości, które ominęły buforowanie Cloudfront.

 138
Author: VKen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:28

Po kilku poprawkach wydaje mi się, że mam to do pracy bez query string hack. Więcej informacji tutaj: http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/RequestAndResponseBehaviorS3Origin.html#RequestS3-cors

Zamierzam przejść przez całą moją konfigurację, aby łatwo było zobaczyć, co zrobiłem, mam nadzieję, że to pomoże innym.

Informacje Ogólne: Używam aplikacji Rails, która ma gem asset_sync, aby umieścić aktywa na S3. Obejmuje to czcionki.

W konsoli S3 kliknąłem na mój bucket, properties I 'Edytuj konfigurację cors', tutaj: CORS Config button

Wewnątrz textarea mam coś takiego:

<?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>

Następnie w Panelu Cloudfront ( https://console.aws.amazon.com/cloudfront/home ) stworzyłem dystrybucję, dodałem pochodzenie, które wskazywało na moje wiadro S3 dodawanie źródła

Następnie dodano zachowanie dla domyślnej ścieżki wskazującej na konfigurację origin i opartą na S3. Co też zrobiłem, to kliknąć na Whitelist nagłówki i Dodane Origin: dodawanie zachowania i nagłówków białej listy

To, co dzieje się teraz, jest następujące, co uważam za słuszne:

1) Sprawdź, czy nagłówki S3 są ustawione poprawnie

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) Sprawdź, czy Cloudfront działa z nagłówkami

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==

(zauważ, że powyższe było pominięciem cloudfront, ponieważ te pliki są buforowane przez 180 sekund, ale to samo działało na hitach)

3) Hit cloudfront z innym pochodzeniem ( ale takim, który jest dozwolony na Kors dla wiadra S3) - Access-Control-Allow-Origin nie jest cached! yay!

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==

Uwaga powyżej, że domena została pomyślnie zmieniona bez hack ciągu zapytania.

Kiedy zmieniam nagłówek Origin, wydaje się, że zawsze jest X-Cache: Miss from cloudfront na pierwszym żądaniu, a następnie otrzymuję oczekiwany X-Cache: Hit from cloudfront

P. S. warto zauważyć, że podczas robienia curl-I (capital I) nie pokaże nagłówków Access-Control-Allow-Origin, ponieważ jest to tylko głowa, robię-i, aby to było GET i przewiń w górę.

 89
Author: Eamonn Gahan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-19 18:47:30

Moje czcionki były serwowane poprawnie aż do ostatniego push to Heroku... Nie wiem dlaczego, ale dzika karta w Kors pozwalała origin przestała działać. Dodałem wszystkie moje domeny prepro i pro do polityki CORS w ustawieniu bucket więc teraz wygląda to tak:

<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: Dodaj swoje http://localhost:PORT too

 13
Author: luigi7up,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-13 18:36:40

Cóż, dokumentacja stwierdza, że możesz umieścić konfigurację jako "podprzewodzące cors w swoim wiadrze."Wziąłem to na myśli, że chciałbym utworzyć plik o nazwie "cors" w korzeniu mojego wiadra z konfiguracją, ale to nie zadziała. W końcu musiałem zalogować się do obszaru administracyjnego Amazon S3 i dodać konfigurację w oknie dialogowym properties mojego wiadra.

S3 przydałaby się lepsza dokumentacja...

 8
Author: nzifnab,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-24 18:51:40

W moim przypadku nie zdefiniowałem przestrzeni nazw XML i wersji w konfiguracji CORS. / Align = "left" /

Zmieniony

<CORSConfiguration>

Do

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
 6
Author: Gaurav Toshniwal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-21 03:48:00

Jest lepszy i łatwiejszy sposób!

Osobiście wolę używać moich poddomen DNS do rozwiązania tego problemu. Jeśli mój CDN jest za cdn.myawesomeapp.com zamiast sdf73n7ssa.cloudfront.net wtedy przeglądarki nie będą freakout i zablokować je jako cross domain problemy bezpieczeństwa.

Aby skierować subdomenę do domeny AWS Cloudfront przejdź do Panelu sterowania AWS Cloudfront, wybierz dystrybucję Cloudfront i wprowadź subdomenę CDN do alternatywnych nazw domen (CNAMEs) pole. Coś jak cdn.myawesomeapp.com zrobi się.

Teraz możesz przejść do swojego dostawcy DNS (jak AWS Route 53) i utworzyć CNAME dla cdn.myawesomeapp.com wskazując na sdf73n7ssa.cloudfront.net.

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

 4
Author: msroot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-02 14:12:57

Ta konfiguracja zadziałała dla mnie. Mogę wyświetlić listę obiektów, pobrać, zaktualizować i usunąć.

<?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>
 4
Author: Shahid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-02 15:36:12
<ifModule mod_headers.c>

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

</ifModule>

Proste Rozwiązanie

 1
Author: O-mkar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-31 01:56:54

In Amazon S3 CORS configuration (S3 Bucket / Permissions / CORS) if you use this:

<?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 działa dobrze dla plików Javascript i CSS, ale nie działa dla plików czcionek .

Musisz określić domenę, aby umożliwić CORS używając wzorca wyrażonego w odpowiedzi @VKen: https://stackoverflow.com/a/25305915/618464

Więc użyj tego :

<?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>

Pamiętaj, aby zastąpić "mydomain.com" dla Twojej domeny.

Po tym, Unieważnij pamięć podręczną CloudFront (CloudFront / Invalidations / Create Invalidation) i będzie działać.

 1
Author: educoutinho,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-01 13:20:45

Ponowne uruchomienie aplikacji (serwera) spring boot rozwiązało problem.

Skonfigurowałem CORSA poprawnie na S3. Curl dawał poprawną odpowiedź z nagłówkiem origin. Safari pobierało poprawnie czcionkę. Tylko chrome nie chciał zaakceptować Kors.

Nie wiem, co dokładnie spowodowało zachowanie. Musi być coś wspólnego z If-modified-since

 0
Author: Sujit Kamthe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-10 11:29:46

Tak, oczywiście. Firefox obsługuje CORS dla czcionek, tak jak wymaga tego Specyfikacja at http://dev.w3.org/csswg/css3-fonts/#allowing-cross-origin-font-loading

 -2
Author: Boris Zbarsky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-02 05:59:03

Doświadczyłem tego samego problemu. Nie musiałem dodawać CNAME do mojego CDD, aby uniknąć problemów z różnymi domenami... Po prostu musiałem zrobić:

Przejdź do Właściwości wiadra - > uprawnienia - > Dodaj więcej uprawnień - > Beneficjent: wszyscy i zaznacz opcję "Lista".

To jest przykład graficzny. http://i.stack.imgur.com/KOEwy.png

Mam nadzieję, że to się komuś przyda.

 -3
Author: Angel Cambero,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-02 20:08:07