J'ai une page web (https://smartystreets.com/contact) qui utilise jQuery pour charger des fichiers SVG depuis S3 via le CDN CloudFront.
Dans Chrome, j'ouvrirai une fenêtre Incognito ainsi que la console. Ensuite, je chargerai la page. Au fur et à mesure que la page se charge, j'obtiendrai généralement 6 à 8 messages dans la console qui ressemblent à ceci :
XMLHttpRequest cannot load
https://d79i1fxsrar4t.cloudfront.net/assets/img/feature-icons/documentation.08e71af6.svg.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'https://smartystreets.com' is therefore not allowed access.
Si je fais un rechargement standard de la page, même plusieurs fois, je continue à obtenir les mêmes erreurs. Si je fais Command+Shift+R
, alors la plupart, et parfois toutes, les images se chargeront sans l'erreur XMLHttpRequest
.
Parfois, même après le chargement des images, si je rafraîchis la page, une ou plusieurs des images ne se chargeront pas et renverront à nouveau cette erreur XMLHttpRequest
.
J'ai vérifié, modifié et revérifié les paramètres sur S3 et Cloudfront. Dans S3, ma configuration CORS ressemble à ceci :
*
http://*
https://*
GET
3000
Authorization
(Remarque : initialement, j'avais seulement *
, même problème.)
Dans CloudFront, le comportement de la distribution est configuré pour autoriser les méthodes HTTP : GET, HEAD, OPTIONS
. Les méthodes mises en cache sont les mêmes. Les entêtes transmis sont configurés sur "Whitelist" et cette liste blanche inclut "Access-Control-Request-Headers, Access-Control-Request-Method, Origin".
Le fait que cela fonctionne après un rechargement du navigateur sans mise en cache semble indiquer que tout va bien du côté de S3/CloudFront, sinon pourquoi le contenu serait-il livré. Mais alors pourquoi le contenu ne serait-il pas livré lors de la consultation initiale de la page ?
Je travaille sur Google Chrome sous macOS. Firefox n'a aucun problème à récupérer les fichiers à chaque fois. Opera NE récupère JAMAIS les fichiers. Safari récupérera les images après plusieurs rafraîchissements.
En utilisant curl
je n'ai aucun problème :
curl -I -H 'Origin: smartystreets.com' https://d79i1fxsrar4t.cloudfront.net/assets/img/phone-icon-outline.dc7e4079.svg
HTTP/1.1 200 OK
Content-Type: image/svg+xml
Content-Length: 508
Connection: keep-alive
Date: Tue, 20 Jun 2017 17:35:57 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
Access-Control-Max-Age: 3000
Last-Modified: Thu, 15 Jun 2017 16:02:19 GMT
ETag: "dc7e4079f937e83291f2174853adb564"
Cache-Control: max-age=31536000
Expires: Wed, 01 Jan 2020 23:59:59 GMT
Accept-Ranges: bytes
Server: AmazonS3
Vary: Origin,Access-Control-Request-Headers,Access-Control-Request-Method
Age: 4373
X-Cache: Hit from cloudfront
Via: 1.1 09fc52f58485a5da8e63d1ea27596895.cloudfront.net (CloudFront)
X-Amz-Cf-Id: wxn_m9meR6yPoyyvj1R7x83pBDPJy1nT7kdMv1aMwXVtHCunT9OC9g==
Certains ont suggéré que je supprime la distribution CloudFront et la recrée. Cela semble être une solution assez radicale et inconfortable.
Quelle est la cause de ce problème ?
Mise à jour :
Ajout des en-têtes de réponse d'une image qui n'a pas pu se charger.
age:1709
cache-control:max-age=31536000
content-encoding:gzip
content-type:image/svg+xml
date:Tue, 20 Jun 2017 17:27:17 GMT
expires:2020-01-01T23:59:59.999Z
last-modified:Tue, 11 Apr 2017 18:17:41 GMT
server:AmazonS3
status:200
vary:Accept-Encoding
via:1.1 022c901b294fedd7074704d46fce9819.cloudfront.net (CloudFront)
x-amz-cf-id:i0PfeopzJdwhPAKoHpbCTUj1JOMXv4TaBgo7wrQ3TW9Kq_4Bx0k_pQ==
x-cache:Hit from cloudfront
0 votes
Vous avez raison - supprimer et recréer est extrême et ne devrait tout simplement jamais être nécessaire. Pouvez-vous nous montrer les en-têtes de requête et de réponse du navigateur pour une requête échouée ? Et peut-être pour une requête réussie du même objet exact ?
0 votes
@Michael-sqlbot, j'espérais un peu que vous visitiez l'URL (smartystreets.com/contact) et voyiez si la même chose se produisait sur votre machine. :) La chose intéressante à propos des erreurs est qu'en dehors de l'erreur dans la console, le navigateur signale un statut de 200, indiquant qu'il utilise l'image "(du cache disque)", ce qui ne devrait pas être possible avec l'Incognito, je pensais. Même après avoir vidé le cache local.
1 votes
Oui, les gens "inventent" si souvent des noms de domaine (qui s'avèrent être de vrais sites, mais pas le site en question) que je n'ai pas réalisé au départ que vous aviez donné le lien réel et correct vers votre site. Merci pour cela, vous pouvez ignorer ma demande. Je peux reproduire le problème. Cela semble être un problème du côté du client. Je suis en train d'explorer une théorie.
0 votes
Je pense que vous pourriez avoir raison en disant qu'il s'agit d'un problème côté client. Les images sont liées avec des balises A dans le HTML, puis il semble qu'elles soient demandées à nouveau dans le jQuery. Peut-être que l'erreur provient d'un appel et que le 200 provient de l'autre.
1 votes
C'est exactement ce que je crois être le cas. Chrome et S3 interagissent de manière à rompre une requête CORS qui suit une requête non-CORS pour le même objet. On pourrait soutenir que les deux ont tort... mais on pourrait aussi soutenir que ni l'un ni l'autre n'a tort. Je ne pense pas que vous puissiez corriger cela sans stocker deux copies de l'objet avec des clés différentes... ou en utilisant deux distributions CloudFront différentes (des noms d'hôtes différents) pour éviter de faire à la fois une requête CORS et une requête non-CORS. Je le rédigerai avec des détails sur la façon dont j'en suis arrivé à cette conclusion, si vous le souhaitez.
1 votes
Lorsque vous manipulez les en-têtes, etc., ils sont mis en cache ; pour revenir aux paramètres actuels, il suffit d'invalided ceux-ci dans CloudFront.
0 votes
Je utilise ce post pour éviter cors dans chrome alfilatov.com/posts/run-chrome-without-cors