Mon application stocke des images sur S3, puis les transmet par proxy via Cloudfront. Je suis ravi d'utiliser le nouveau support S3 CORS afin de pouvoir utiliser les méthodes de canevas HTML5 (qui ont une politique cross-Origin) mais je n'arrive pas à configurer correctement mon S3 et Cloudfront. Toujours en cours d'exécution "Erreur non capturée: SECURITY_ERR: exception DOM 18" lorsque j'essaie de convertir une image en élément de canevas.
Voici ce que j'ai jusqu'à présent:
S3
<CORSConfiguration>
<CORSRule>
<AllowedOrigin>MY_WEBSITE_URL</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
<CORSRule>
<AllowedOrigin>MY_CLOUDFRONT_URL</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
Cloudfront
Les origines
Origin Protocol Policy: Match Viewer
HTTP Port: 80
HTTPS Port: 443
Comportements
Origin: MY_WEBSITE_URL
Object Caching: Use Origin Cache Headers
Forward Cookies: None
Forward Query Strings: Yes
Y a-t-il quelque chose qui me manque ici?
MISE À JOUR: J'ai juste essayé de changer les en-têtes en
<AllowedHeader>Content-*</AllowedHeader>
<AllowedHeader>Host</AllowedHeader>
basé sur cette question Amazon S3 CORS (Cross-Origin Resource Sharing) et Firefox cross-domain font loading
Toujours pas.
MISE À JOUR: PLUS D'INFO SUR DEMANDE
Request
URL:https://d1r5nr1emc2xy5.cloudfront.net/uploaded/BAhbBlsHOgZmSSImMjAxMi8wOS8xMC8xOC81NC80Mi85NC9ncmFzczMuanBnBjoGRVQ/32c0cee8
Request Method:GET
Status Code:200 OK (from cache)
MISE À JOUR
Je pense que ma demande n'était peut-être pas correcte, j'ai donc essayé d'activer CORS avec
img.crossOrigin = '';
mais alors l'image ne se charge pas et j'obtiens l'erreur: charge d'image Cross-Origin refusée par la stratégie de partage de ressources Cross-Origin.
Le 26 juin 2014, AWS a publié bon comportement Vary: Origin sur CloudFront alors maintenant vous venez
Définissez une configuration CORS pour votre compartiment S3, y compris
<AllowedOrigin>*</AllowedOrigin>
Dans CloudFront -> Distribution -> Comportements pour cette origine
Origin
.Attendez environ 20 minutes pendant que CloudFront propage la nouvelle règle
Désormais, votre distribution CloudFront doit mettre en cache différentes réponses (avec les en-têtes CORS appropriés) pour différents en-têtes d'origine du client.
Pour compléter @ réponse de Brett . Il existe des pages de documentation AWS détaillant CORS sur CloudFront et CORS sur S .
Les étapes détaillées ici sont les suivantes:
<AllowedOrigin>
la règle est la plus importante. Enregistrez la configuration. OPTIONS
réponses soient mises en cache ou non, il existe deux manières selon AWS:
- Si vous souhaitez que les réponses OPTIONS soient mises en cache, procédez comme suit:
- Choisissez les options des paramètres de comportement de cache par défaut qui permettent la mise en cache des réponses OPTIONS.
- Configurez CloudFront pour transférer les en-têtes suivants: origine, en-têtes de demande de contrôle d'accès et méthode de demande de contrôle d'accès.
- Si vous ne souhaitez pas que les réponses OPTIONS soient mises en cache, configurez CloudFront pour transférer l'en-tête Origin, ainsi que tous les autres en-têtes requis par votre origine
Et avec ce CORS de CloudFront avec S3 devrait fonctionner.
MISE À JOUR: ce n'est plus vrai avec les changements récents sur CloudFront. Hourra! Voir les autres réponses pour les détails. Je laisse cela ici pour le contexte/l'histoire.
Problème
CloudFront ne prend pas en charge CORS à 100%. Le problème est de savoir comment CloudFront met en cache la réponse à la demande. Toute autre demande pour la même URL après cela entraînera la demande en cache peu importe l'origine. La partie clé à ce sujet est qu'elle inclut les en-têtes de réponse de l'origine.
Première demande avant que CloudFront n'ait quoi que ce soit mis en cache de Origin: http://example.com
a un en-tête de réponse:
Access-Control-Allow-Origin: http://example.com
Deuxième demande de Origin: https://example.com
(notez qu'il s'agit de HTTPS et non de HTTP) a également l'en-tête de réponse:
Access-Control-Allow-Origin: http://example.com
Parce que c'est ce que CloudFront a mis en cache pour l'URL. Ceci n'est pas valide - la console du navigateur (en Chrome au moins) affichera un message de violation CORS et les choses vont se casser.
Solution
Le travail suggéré consiste à utiliser différentes URL pour différentes origines. L'astuce consiste à ajouter une chaîne de requête unique qui est différente afin qu'il y ait un enregistrement mis en cache par origine.
Donc, nos URL seraient quelque chose comme:
http://.../some.png?http_mysite.com
https://.../some.png?https_mysite.com
Ce genre de travaux, mais n'importe qui peut mal faire fonctionner votre site en échangeant les chaînes de requête. Est-ce probable? Probablement pas, mais le débogage de ce problème est un énorme problème.
La bonne solution consiste à ne pas utiliser CloudFront avec CORS tant qu'ils ne prennent pas pleinement en charge CORS.
En pratique
Si vous utilisez CloudFront pour CORS, utilisez une autre méthode qui fonctionnera lorsque CORS ne fonctionne pas. Ce n'est pas toujours une option mais en ce moment je charge dynamiquement des polices avec JavaScript. Si la demande basée sur CORS à CloudFront échoue, je reviens à un proxy côté serveur pour les polices (pas d'origine croisée). De cette façon, les choses continuent de fonctionner même si CloudFront a en quelque sorte obtenu un mauvais enregistrement mis en cache pour la police.
Je ne sais pas exactement quel est votre problème, mais:
https://forums.aws.Amazon.com/thread.jspa?messageID=37751
répondu à certains de mes problèmes avec CORS, S3 et Cloudfront.
J'ai également constaté que certains actifs d'un compartiment reviendraient avec les en-têtes CORS corrects et d'autres non. Après avoir invalidé les actifs, ils sont tous revenus avec des en-têtes corrects, ne sachant pas pourquoi certains devaient être invalidés et d'autres pas car ils ont été téléchargés en même temps, même type, même seau :(