web-dev-qa-db-ja.com

Safariで(CloudFrontから)クロスオリジンイメージを読み込めません

Safari8でCloudFrontURLから画像を読み込もうとすると、次のエラーが発生します。
Cross-Origin image load denied by Cross-Origin Resource Sharing policy.

これはSafari8でのみ発生します。FireFox38およびChrome 41最新では正常にロードされます。(Mac10.10)

私のセットアップ:

1。次のCORS構成のS3バケット

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

2。リンクされたCloudFrontディストリビューション

次のヘッダーがホワイトリストに登録されています(動作下)。

  • Access-Control-Request-Headers
  • Access-Control-Request-Method
  • Origin

。JavaScript

var img = new Image();
img.crossOrigin = '';
img.onload = function() {
  console.log('image loaded');
}

私が試したこと:

1。curlから返されたヘッダーを確認する

画像は正しいヘッダーを返しています(特にAccess-Control-Allow-Origin

> curl -sI -H 'Origin: localhost' -H 'Access-Control-Request-Method: GET' http://foo.cloudfront.com/image.jpg
...
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
Access-Control-Max-Age: 3000
Server: AmazonS3
Vary: Origin,Access-Control-Request-Headers,Access-Control-Request-Method
X-Cache: Hit from cloudfront

2。ブラウザで返されたヘッダーを確認する

興味深いことに、画像は3つのブラウザすべてでAccess-Control-Allow-Origin: *ヘッダーを返していません。なぜそうなるのでしょうか?

。URLへのクエリ文字列の追加

ロードされるURLにクエリ文字列(例:?foo)を追加すると、ブラウザにAccess-Control-Allow-Originヘッダーが返され、Safariに画像をロードできるようになります。これは素晴らしいことですが、クエリ文字列を追加するとこれが機能する(そしてAccess-Control-Allow-Originヘッダーも返す)のはなぜですか?

4。S3バケットからのイメージのロード(CloudFrontディストリビューションに関連付けられていない)

CloudFrontに関連付けられていない(同じCORS構成を持つ)別のバケットからのイメージのロードも、Safariで問題なく機能します。

これは当初、これが特にCloudFrontの問題であると私に信じさせましたが、クエリ文字列に関する上記の点は私に別のことを考えさせます。

これは私を完全にバタバタさせています。誰かが上記に光を当てるのを手伝ってくれる?


更新

返信ありがとうございます。苛立たしいことに、私はこの問題を再現できないようです。

以下は、2つの画像(1つはS3バケットから、もう1つはそれぞれのCloudfrontディストリビューションから)をロードするスニペットです。これらは両方とも、上記のポイント#2で述べたのとは逆に、期待するヘッダーで問題なくロードされているように見えます。 。

残念ながら、私は明確な答えに実際には近づいていませんが、今のところ、私に代わってエラーにチョークで書き、Derekが提案したようにCORSセットアップの前に画像を要求する可能性があります。

var img, imgCloudfront;

img = new Image();
img.crossOrigin = '';
img.onload = function() {
  $('body').append('image loaded<br>');
}
img.src = 'http://sandbox-robinpyon.s3.amazonaws.com/test.jpg';

imgCloudfront = new Image();
imgCloudfront.crossOrigin = '';
imgCloudfront.onload = function() {
 $('body').append('image (cloudfront) loaded<br>');
}
imgCloudfront.src = 'http://d32d4njimxij7s.cloudfront.net/test.jpg';
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
14
Robin Pyon

クラウドフロントの動作設定をダブルチェックアウトします。カスタムヘッダーOriginを追加しましたか。そのはず Access-Control-Allow-Origin。最近、cloudfrontもセットアップしましたが、この記事が役に立ちました: http://kennethjiang.blogspot.com/2014/07/set-up-cors-in-cloudfront-for-custom.html

クラウドフロントのキャッシュをクリアする際に問題が発生しました。 CORSセットアップの前にイメージをリクエストした場合、cloudfrontは以前のイメージを返すだけなので、新しい設定は反映されません。無効化を実行してみることができます。これは、クラウドフロントの動作タブの1つです。これで一貫性のない結果が得られました。それが機能していることを確認したい場合は、新しい画像をアップロードしてそれでテストしてください。私はRailsを使用していますが、アセットのバージョンを上げると、すべてのアセットに新しいフィンガープリントが作成され、各ファイルの名前が新しいため、キャッシュの問題が解決されることがあります。)

クエリ文字列に関する質問について。おそらくクラウドフロントからキャッシュミスが発生しました。 curlを使用して演習を繰り返し、応答を確認できますX-Cache: Hit from cloudfrontが存在するかどうか。クラウドフロントの動作設定には、「ForwardQueryStrings」の設定があります。それが要因になるかもしれません。

私のセットアップでは、中間のワニスキャッシュがあったので、すべてのヘッダーが確実に通過するように、それもいじる必要がありました。あなたはそれを持っているようには見えませんが、それは注意すべきことです。

7
Derek

参照: https://stackoverflow.com/a/13147554/1994767

Access-Control-Allow-Headers(<AllowedHeader>*</AllowedHeader>)ヘッダーはワイルドカードを許可しません。完全に一致する必要があります: http://www.w3.org/TR/cors/#access-control-allow-headers-response-header

5
Jakeii

それは単なる推測ですが、欠落しているAccess-Control-Allow-Originヘッダーは私にとって重要なポイントのようです。いくつかの理由で、他のブラウザはそれなしで実行できますが、Safariは実行できません。
CloudFront設定をいじってみましたか?ホワイトリストに登録する代わりにすべてのヘッダーを転送したり、クエリ文字列の転送設定を変更したりします。そして、他の人が言っているように、私たちが自分自身をチェックできるように、テストURLを提供してください。

3
Antoine

ブラウザのキャッシュをクリーンアップしてみてください。

これが機能しない場合は、サンプル画像のURLを入力してください。

2
wookieb

これはブラウザのキャッシュに関連していると思います。

S3が非CORSリクエストの「Vary:Origin」ヘッダーを省略している問題があります。これにより、一部のブラウザは非CORS応答をキャッシュし、CORSを必要とする後続のリクエストでこのキャッシュされた応答を再利用し、ブラウザが「クロスオリジンリソースシェアリングポリシーによって拒否されたクロスオリジンイメージのロード」をスローします。エラー。

詳細については、以下を参照してください。 S3 CORS、常にVary:Originを送信

この問題は AWS S3フォーラム でも報告されています

1