web-dev-qa-db-fra.com

Impossible de charger une image d'origine croisée (depuis CloudFront) dans Safari

L'erreur suivante s'affiche lorsque j'essaie de charger une image à partir d'une URL CloudFront dans Safari 8:
Cross-Origin image load denied by Cross-Origin Resource Sharing policy.

Cela ne se produit que sur Safari 8. Sous FireFox 38 et Chrome 41, il se charge très bien. (Mac 10.10)

Ma configuration:

1. Seau S3 avec la configuration CORS suivante

<?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. Une distribution CloudFront liée

Les en-têtes suivants ont été ajoutés à la liste blanche (sous comportements):

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

3. JavaScript

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

Ce que j'ai essayé

1. Vérification des en-têtes renvoyés à curl

L'image renvoie les en-têtes corrects (notamment 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. Vérification des en-têtes renvoyés dans le navigateur

Chose intéressante, l’image ne renvoie PAS l’en-tête Access-Control-Allow-Origin: * dans les trois navigateurs. Pourquoi serait-ce le cas?

3. Ajout d'une chaîne de requête à l'URL

L'ajout d'une chaîne de requête (par exemple? Foo) à l'URL en cours de chargement entraîne le renvoi de l'en-tête Access-Control-Allow-Origin dans le navigateur et permet le chargement de l'image dans Safari! C'est bien, mais pourquoi l'ajout de la chaîne de requête permettrait-il que cela fonctionne (et renvoie également l'en-tête Access-Control-Allow-Origin)?

4. Chargement d'une image à partir d'un compartiment S3 (non lié à une distribution CloudFront)

Le chargement d'une image à partir d'un autre compartiment non lié à CloudFront (avec une configuration CORS identique) fonctionne également très bien dans Safari. 

Ce qui, au départ, m'a amené à croire qu'il s'agissait spécifiquement d'un problème CloudFront, mais le point ci-dessus avec la chaîne de requête me fait penser le contraire.

Cela me rend complètement fou. Quelqu'un peut-il aider à faire la lumière sur ce qui précède?


Mettre à jour

Merci pour les réponses. Frustrement, je n'arrive pas à reproduire ce problème.

Vous trouverez ci-dessous un extrait qui charge deux images (une d'un compartiment S3, une autre de leur distribution Cloudfront respective) et qui semblent également se charger parfaitement avec les en-têtes que vous attendez, contrairement à ce que j'ai dit au point 2 ci-dessus. .

Malheureusement, je ne suis pas vraiment sur le point de donner une réponse définitive, mais pour le moment, je vais simplement m'en tenir à une erreur de ma part, demandant potentiellement une image avant la configuration de ma CORS, comme suggéré par Derek.

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

Double checkout vos paramètres de comportement cloudfront. Avez-vous ajouté l'en-tête personnalisé Origin. Ce devrait être Access-Control-Allow-Origin. J'ai récemment installé cloudfront également et trouve cet article utile: http://kennethjiang.blogspot.com/2014/07/set-up-cors-in-cloudfront-for-custom.html

J'ai eu des problèmes pour vider le cache sur Cloudfront. Si vous aviez demandé une image avant la configuration de votre CORS, cloudfront peut simplement renvoyer ce qu'il avait précédemment afin que vos nouvelles configurations ne soient pas reflétées. Vous pouvez essayer d'exécuter une invalidation, c'est l'un des onglets de comportement de cloudfront. J'ai eu des résultats incohérents avec cela. Si vous voulez vous assurer que cela fonctionne, téléchargez une nouvelle image et testez-la. J'utilise Rails et, à l'occasion, je bosse une version d'actif, ce qui entraîne une nouvelle empreinte digitale pour tous mes actifs, ce qui résout les problèmes de mise en cache car chaque fichier porte un nouveau nom.)

En ce qui concerne votre question sur la chaîne de requête. Vous avez probablement un cache cache de Cloudfront. Vous pouvez essayer de répéter l'exercice avec curl pour voir si la réponse X-Cache: Hit from cloudfront est présente ou non. Dans les paramètres de comportement de cloudfront, il existe une configuration pour les "chaînes de requête". Cela peut jouer un facteur.

Dans ma configuration, j’avais un cache de vernis intermédiaire, j’ai donc dû le manipuler aussi pour être sûr que tous les en-têtes le traversent. Ça ne semble pas être comme ça, mais c'est une chose à surveiller.

7
Derek

Voir: https://stackoverflow.com/a/13147554/1994767

L'en-tête Access-Control-Allow-Headers (<AllowedHeader>*</AllowedHeader>) n'autorise pas les caractères génériques. Ce doit être une correspondance exacte: http://www.w3.org/TR/cors/#access-control-allow-headers-response-header

5
Jakeii

C'est juste une supposition, mais l'en-tête manquant de Access-Control-Allow-Origin semble être le point clé pour moi. Pour certaines raisons, d'autres navigateurs peuvent s'en passer, mais pas Safari.
Avez-vous essayé de modifier votre configuration CloudFront? Cela ressemble au transfert de tous les en-têtes au lieu de la mise en liste blanche ou de la modification du paramètre de transfert de chaîne de requête. Et comme d’autres l’ont déjà dit, veuillez fournir une URL de test afin que nous puissions vérifier nous-mêmes.

3
Antoine

Essayez de nettoyer le cache du navigateur. 

Si cela ne fonctionne pas, veuillez fournir l'URL d'un exemple d'image.

2
wookieb

Je suppose que cela est lié au cache du navigateur.

Il y a un problème où S3 omet un en-tête "Variable: Origine" pour les demandes non-CORS. Cela amène certains navigateurs à mettre en cache une réponse non-CORS et à réutiliser cette réponse dans des requêtes ultérieures nécessitant une connexion CORS. Erreur.

Pour plus de détails, voir: S3 CORS, envoyez toujours Vary: Origin

Le problème a également été signalé sur le AWS S3 Forums

1
Kristian Hanekamp