web-dev-qa-db-ja.com

Amazon S3 CORS(クロスオリジンリソース共有)およびFirefoxクロスドメインフォントの読み込み

Firefoxには、現在のWebページとは異なるOriginからフォントが読み込まれないという長年の問題があります。通常、フォントがCDNで提供されるときに問題が発生します。

他の質問でもさまざまな解決策が提起されています。

CSS @ font-faceはFirefoxでは動作しませんが、ChromeおよびIEでは動作します

Amazon S3 CORSの導入で、CORSを使用してFirefoxのフォントの読み込みの問題に対処するソリューションはありますか?

編集:S3 CORS構成のサンプルを見ることは素晴らしいことです。

edit2:実際にそれが何をしたのか理解せずに、実用的なソリューションを見つけました。 Amazonの設定の解釈で発生する設定と背景の魔法についてより詳細な説明を誰かが提供できれば、賞金を支払ったnzifnabのように大歓迎です。

127
VKen

2014年9月10日更新:

CloudfrontがCORSを適切にサポートするようになったため、以下のクエリ文字列のハックを行う必要はもうありません。 http://aws.Amazon.com/blogs/aws/enhanced-cloudfront-customization/ および詳細についてはこの回答を参照してください: https://stackoverflow.com/a/25305915/308315


わかりました。ドキュメントの例から少し調整して、次の設定を使用してフォントが機能するようになりました。

私のフォントはS3でホストされていますが、フロントはクラウドフロントです。

なぜ機能するのかわかりませんが、おそらく<AllowedMethod>GET<AllowedHeader>Content-*が必要だと思います。

Amazon S3 CORSの設定に精通している人なら、この点についていくつかのライトを当てることができれば、大歓迎です。

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

編集:

一部の開発者は、Access-Control-Allow-OriginヘッダーをキャッシュするCloudfrontの問題に直面しています。この問題は、以下のリンク( https://forums.aws.Amazon.com/thread.jspa?threadID=114646 )でAWSスタッフによって対処されており、@ Jeff-Atwoodによってコメントされています。

回避策として、リンクされたスレッドから、異なるドメインからの呼び出しを区別するためにQuery Stringを使用することをお勧めします。ここで短縮例を再現します。

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キャッシングを通過したことに気付くでしょう。

139
VKen

少し調整した後、クエリ文字列のハッキングなしでこれを動作させることができたようです。詳細はこちら: http://docs.aws.Amazon.com/AmazonCloudFront/latest/DeveloperGuide/RequestAndResponseBehaviorS3Origin.html#RequestS3-cors

私が行ったことを簡単に確認できるように、セットアップ全体を実行します。これが他の人の助けになることを願っています。

背景情報:asset_sync gemを含むRailsアプリを使用して、アセットをS3に配置します。これにはフォントが含まれます。

S3コンソール内で、バケット、プロパティ、および「cors設定の編集」をクリックしました。 CORS config button

テキストエリア内には次のようなものがあります:

<?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バケットを指すOriginを追加しました adding an Origin

次に、デフォルトパスがS3ベースのOrigin 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==

(これらのファイルは180秒間キャッシュされるため、上記はcloudfrontのミスでしたが、ヒットでも同じように機能していました)

3)異なるオリジン(ただし、S3バケットのCORSで許可されているオリジン)でクラウドフロントをヒットします-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が表示されるようです

追伸curl -I(capital I)を実行するとき、Access-Control-Allow-OriginヘッダーはHEADのみであるため表示されないことに注意する価値があります。

89
Eamonn Gahan

フォントは、最後のPush to Herokuまで正しく配信されました...理由はわかりませんが、CORSのワイルドカードにより、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>

更新:http://localhost:PORTも追加します

13
luigi7up

さて、ドキュメントには、「バケット内のcorsサブリソース」として構成を固定できることが記載されています。これは、設定を使用してバケットのルートに「cors」というファイルを作成することを意味しますが、これは機能しません。最後に、Amazon S3管理エリアにログインし、バケットのpropertiesダイアログ内に構成を追加する必要がありました。

S3はいくつかのより良いドキュメントを使用できます...

8
nzifnab

私の場合、CORS構成でXML名前空間とバージョンを定義していませんでした。働いたものを定義する。

かわった

<CORSConfiguration>

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

Amazon S3の場合CORS設定(S3バケット/許可/ 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ファイルに対しては正常に機能しますが、Fontファイルに対しては機能しません

@VKen回答で表されたパターンを使用してCORSを許可するには、ドメインを指定する必要があります。 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/Invalidations/Create Invalidation)と動作します。

5
educoutinho

この構成はうまくいきました。オブジェクトを一覧表示、取得、更新、削除できます。

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

より良い簡単な方法があります!

個人的には、DNSサブドメインを使用してこの問題を解決することを好みます。 CDNがsdf73n7ssa.cloudfront.netではなくcdn.myawesomeapp.comの背後にある場合、ブラウザーはクロスドメインセキュリティの問題としてフリークアウトしてブロックしません。

サブドメインをAWS Cloudfrontドメインにポイントするには、AWS Cloudfrontコントロールパネルに移動し、Cloudfrontディストリビューションを選択して、CDNサブドメインを[代替ドメイン名(CNAME)]フィールドに入力します。 cdn.myawesomeapp.comのようなことができます。

これで、DNSプロバイダー(AWS Route 53など)に移動し、sdf73n7ssa.cloudfront.netを指すcdn.myawesomeapp.comのCNAMEを作成できます。

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

4
msroot
<ifModule mod_headers.c>

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

</ifModule>

シンプルなソリューション

1
O-mkar

春のブートアプリケーション(サーバー)を再起動すると、問題が解決しました。

S3でCORSを正しく構成しました。カールは、Originヘッダーで正しい応答を提供していました。 Safariはフォントを正しく取得していました。 CORSを受け入れたくないのはchromeだけでした。

正確に何が動作を引き起こしたのか分かりません。 If-modified-sinceに関係する必要があります

0
Sujit Kamthe