web-dev-qa-db-fra.com

Erreur CORS même après avoir défini Access-Control-Allow-Origin côté client

J'ai une application Vue générée avec webpack-simple option. J'essaie de faire une demande de GET à https://api.forismatic.com/api/1.0/?method=getQuote&format=json&lang=en mais j'obtiens l'erreur:

XMLHttpRequest ne peut pas charger https://api.forismatic.com/api/1.0/?method=getQuote&format=json&lang=en. La réponse à la demande de contrôle en amont ne passe pas la vérification du contrôle d'accès: aucun en-tête "Access-Control-Allow-Origin" n'est présent sur la ressource demandée. Origine 'http://127.0.0.1:8080 'n'est donc pas autorisé à accéder.

J'utilise vue-resource et j'ai ajouté:

Vue.http.headers.common['Access-Control-Allow-Origin'] = '*'

Cela n'a aucun effet.

J'ai également ajouté cela dans l'option devServer dans webpack.config.js:

devServer: {
  historyApiFallback: true,
  noInfo: true,
  headers: {
    "Access-Control-Allow-Origin": "*"
  }
}

Cela ne résout pas non plus le problème; le message d'erreur reste le même.

Comment résoudre ce problème?

10
wrahim

Access-Control-Allow-Origin est un en-tête de réponse que le serveur auquel la requête doit envoyer doit envoyer.

Mais https://api.forismatic.com/api/1.0/?method=getQuote&format=json&lang=en n'envoie pas le Access-Control-Allow-Origin header - vous devez donc faire la demande via un proxy. Pour ce faire, modifiez votre code JavaScript frontal pour utiliser à la place cette URL:

https://cors-anywhere.herokuapp.com/https://api.forismatic.com/api/1.0/?method=getQuote&format=json&lang=en

Essayez cela et votre code frontal fonctionnera comme prévu. Mais assurez-vous d'abord de supprimer également ceci:

Vue.http.headers.common['Access-Control-Allow-Origin'] = '*'

C'est ajouter le Access-Control-Allow-Origin en-tête de la demande , en tant qu'en-tête de demande. Mais comme mentionné ci-dessus, Access-Control-Allow-Origin est un en-tête de réponse . Donc, le seul effet que vous avez en ajoutant Access-Control-Allow-Origin à la demande est que vous déclenchez votre navigateur pour envoyer ne demande de contrôle en amont CORS OPTIONS plutôt que d'envoyer votre GET.

Et accessoirement, vous pouvez également supprimer ceci:

headers: {
  "Access-Control-Allow-Origin": "*"
}

Tout ce qui semble être de faire est d'ajouter le Access-Control-Allow-Origin en-tête de réponse aux réponses de votre propre serveur principal. Mais la demande que fait votre code frontal ne va pas à votre propre serveur principal, mais plutôt à https://api.forismatic.com/.

Quoi qu'il en soit, le https://cors-anywhere.herokuapp.com/https://api.forismatic.com/… L'URL entraînera l'envoi de la demande à https://cors-anywhere.herokuapp.com, un proxy CORS ouvert/public qui envoie la demande à https://api.forismatic.com/api/1.0/?method=getQuote….

Et lorsque ce proxy recevra la réponse, il la prendra et ajoutera le Access-Control-Allow-Origin en-tête de réponse, puis renvoyez-le à votre code frontal demandeur comme réponse.

Cette réponse avec le Access-Control-Allow-Origin l'en-tête de réponse est ce que voit le navigateur, donc le message d'erreur que le navigateur vous montre disparaît maintenant, et le navigateur permet à votre code JavaScript frontal d'accéder à la réponse.

Ou utilisez le code de https://github.com/Rob--W/cors-anywhere/ ou similaire pour configurer votre propre proxy.

La raison pour laquelle vous avez besoin d'un proxy est, https://api.forismatic.com/api/1.0/?method=getQuote… lui-même n'envoie pas le Access-Control-Allow-Origin en-tête de réponse, donc votre navigateur refusera de laisser votre code JavaScript frontal accéder à une réponse de ce serveur d'origine croisée.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS a plus de détails.

15
sideshowbarker