Question Comment fonctionne l'en-tête Access-Control-Allow-Origin?


Apparemment, j'ai complètement mal compris sa sémantique. J'ai pensé à quelque chose comme ça:

  1. Un client télécharge le code javascript MyCode.js depuis http: // siteA - l'origine.
  2. L'en-tête de réponse de MyCode.js contient Access-Control-Allow-Origine: http: // siteB, ce que je pensais signifier que MyCode.js était autorisé à faire des références d'origine croisée au site B.
  3. Le client déclenche une fonctionnalité de MyCode.js, qui à son tour envoie des requêtes à http: // siteB, ce qui devrait être correct, bien qu'il s'agisse de requêtes d'origine croisée.

Eh bien, j'ai tort. Ça ne marche pas du tout comme ça. Donc, j'ai lu Partage de ressources inter-origine et a tenté de lire Partage de ressources inter-origine dans la recommandation W3C

Une chose est sûre - je ne comprends toujours pas comment je suis supposé utiliser cet en-tête.

J'ai le contrôle total du site A et du site B. Comment activer le code javascript téléchargé depuis le site A pour accéder aux ressources du site B en utilisant cet en-tête?

P.S.

Je ne veux pas utiliser JSONP.


787
2018-05-17 13:23


origine


Réponses:


Access-Control-Allow-Origin est un En-tête CORS (Cross-Origin Resource Sharing).

Lorsque le site A tente d'extraire du contenu du site B, le site B peut envoyer un Access-Control-Allow-Origin en-tête de réponse pour indiquer au navigateur que le contenu de cette page est accessible à certaines origines. (Un origine est un domaine, plus un schéma et un numéro de port.) Par défaut, les pages du site B sont pas accessible à une autre origine; en utilisant le Access-Control-Allow-Origin En-tête ouvre une porte pour l'accès d'origine croisée par des origines de demande spécifiques.

Pour chaque ressource / page que le site B veut rendre accessible au site A, le site B devrait diffuser ses pages avec l'en-tête de réponse:

Access-Control-Allow-Origin: http://siteA.com

Les navigateurs modernes ne bloqueront pas les demandes inter-domaines. Si le site A demande une page à partir du site B, le navigateur récupèrera la page demandée au niveau du réseau et vérifiez si les en-têtes de réponse répertorient le site A en tant que domaine de demandeur autorisé. Si le Site B n'a pas indiqué que le Site A est autorisé à accéder à cette page, le navigateur déclenchera XMLHttpRequestde error événement et refuser les données de réponse au code JavaScript demandeur.

Demandes non simples

Ce qui se passe au niveau du réseau peut être légèrement plus complexe qu'expliqué ci-dessus. Si la requête est un demande "non simple", le navigateur envoie d'abord une requête OPTIONS "preflight" sans données, pour vérifier que le serveur acceptera la requête. Une requête n'est pas simple quand (ou les deux):

  • en utilisant un verbe HTTP autre que GET ou POST (par exemple PUT, DELETE)
  • utiliser des en-têtes de requête non simples; les seuls en-têtes de requêtes simples sont:
    • Accept
    • Accept-Language
    • Content-Language
    • Content-Type (Ceci est seulement simple quand sa valeur est application/x-www-form-urlencoded, multipart/form-data, ou text/plain)

Si le serveur répond au contrôle en amont OPTIONS avec les en-têtes de réponse appropriés (Access-Control-Allow-Headers pour les en-têtes non simples, Access-Control-Allow-Methodspour les verbes non simples) qui correspondent au verbe non simple et / ou aux en-têtes non simples, le navigateur envoie la requête réelle.

Supposons que le site A souhaite envoyer une demande PUT pour /somePage, avec un non-simple Content-Type valeur de application/json, le navigateur envoie d'abord une demande de contrôle en amont:

OPTIONS /somePage HTTP/1.1
Origin: http://siteA.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Content-Type

Notez que Access-Control-Request-Method et Access-Control-Request-Headers sont ajoutés automatiquement par le navigateur; vous n'avez pas besoin de les ajouter. Ce contrôle en amont OPTIONS obtient les en-têtes de réponse réussis:

Access-Control-Allow-Origin: http://siteA.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type

Lors de l'envoi de la requête actuelle (après le contrôle en amont), le comportement est identique à celui d'une simple requête. En d'autres termes, une requête non simple dont le contrôle en amont est réussi est traitée comme une simple requête (c'est-à-dire que le serveur doit toujours envoyer Access-Control-Allow-Origin encore une fois pour la réponse réelle).

Les navigateurs envoient la requête actuelle:

PUT /somePage HTTP/1.1
Origin: http://siteA.com
Content-Type: application/json

{ "myRequestContent": "JSON is so great" }

Et le serveur renvoie un Access-Control-Allow-Origin, comme pour une simple demande:

Access-Control-Allow-Origin: http://siteA.com

Voir Comprendre XMLHttpRequest sur CORS pour un peu plus d'informations sur les demandes non-simples.


1020
2018-05-17 13:33



Partage de demande d'origine croisée - CORS (Demande AJAX interdomaine A.K.A) est un problème que la plupart des développeurs Web peuvent rencontrer, selon la règle Same-Origin, les navigateurs limitent le JavaScript client dans un sandbox de sécurité, généralement JS ne peut pas communiquer directement avec un serveur distant d'un domaine différent. Dans le passé, les développeurs ont créé de nombreux moyens compliqués pour obtenir des requêtes de ressources inter-domaines, les plus courantes étant les suivantes:

  1. Utilisez Flash / Silverlight ou le côté serveur comme "proxy" pour communiquer avec télécommande.
  2. JSON avec rembourrage (JSONP).
  3. Embarque le serveur distant dans un iframe et communique par fragment ou par window.name, référez-vous ici.

Ces méthodes délicates ont plus ou moins quelques problèmes, par exemple JSONP pourrait entraîner un trou de sécurité si les développeurs "évaluent" simplement, et # 3 ci-dessus, bien que cela fonctionne, les deux domaines devraient contracter entre eux, il n'est ni flexible ni élégant A MON HUMBLE AVIS:)

Le W3C avait introduit le partage de ressources d'origine croisée (CORS) comme solution standard pour fournir un moyen standard sûr, flexible et recommandé pour résoudre ce problème.

Le mécanisme

D'un niveau élevé, nous pouvons simplement considérer que CORS est un contrat entre l'appel AJAX du client du domaine A et une page hébergée sur le domaine B, une demande / réponse d'origine croisée typique serait:

En-têtes de requête DomainA AJAX

Host DomainB.com
User-Agent Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0) Gecko/20100101 Firefox/4.0
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,application/json
Accept-Language en-us;
Accept-Encoding gzip, deflate
Keep-Alive 115
Origin http://DomainA.com 

En-têtes de réponse DomainB

Cache-Control private
Content-Type application/json; charset=utf-8
Access-Control-Allow-Origin DomainA.com
Content-Length 87
Proxy-Connection Keep-Alive
Connection Keep-Alive

Les parties bleues marquées ci-dessus étaient les faits kernaux, l'en-tête de requête "Origine" indique "d'où provient la demande d'origine croisée ou la demande de contrôle", l'en-tête de réponse "Access-Control-Allow-Origin" indique que cette page permet DomainA (si la valeur est * indique permet des demandes à distance de n'importe quel domaine).

Comme je l'ai mentionné ci-dessus, W3 navigateur recommandé pour mettre en œuvre un "demande de contrôle en amont"avant de soumettre la requête HTTP Cross-Origin, en un mot c'est un HTTP OPTIONS demande:

OPTIONS DomainB.com/foo.aspx HTTP/1.1

Si foo.aspx supporte le verbe OPTIONS HTTP, il peut renvoyer une réponse comme ci-dessous:

HTTP/1.1 200 OK
Date: Wed, 01 Mar 2011 15:38:19 GMT
Access-Control-Allow-Origin: http://DomainA.com
Access-Control-Allow-Methods: POST, GET, OPTIONS, HEAD
Access-Control-Allow-Headers: X-Requested-With
Access-Control-Max-Age: 1728000
Connection: Keep-Alive
Content-Type: application/json

Uniquement si la réponse contient "Access-Control-Allow-Origin" AND sa valeur est "*" ou contient le domaine qui a soumis la requête CORS, en vérifiant que le navigateur de conditions de mandtory soumettra la demande inter-domaine et mettra en cache le résultat dans "Preflight-Result-Cache".

J'ai blogué sur CORS il y a trois ans: Requête HTTP AJAX Cross-Origin


102
2018-01-23 13:54



La question est un peu trop vieille pour répondre, mais je la poste pour toute référence future à cette question.

Selon ce Article du Mozilla Developer Network,

Une ressource fait un requête HTTP d'origine croisée quand il demande une ressource d'un autre domaine, ou port que celui que la première ressource elle-même sert.

enter image description here

Un Page HTML servi à partir de http://domain-a.com fait un <img> demande src pour http://domain-b.com/image.jpg.
De nombreuses pages sur le Web chargent aujourd'hui des ressources comme Feuilles de style CSS, images et scripts à partir de domaines distincts (il devrait donc être cool).

Politique de même origine

Pour des raisons de sécurité, les navigateurs restreignent HTTP d'origine croisée demande initié à partir de scripts.
Par exemple, XMLHttpRequest et Fetch suivre la politique de même origine.
Donc, une application web utilisant XMLHttpRequest ou Fetch ne pouvait que faire Requêtes HTTP à son propre domaine.

Partage de ressources inter-origine (CORS)

Pour améliorer les applications Web, les développeurs ont demandé aux fournisseurs de navigateurs d'autoriser les demandes inter-domaines.

le Partage de ressources inter-origine (CORS) mécanisme donne des serveurs Web contrôles d'accès inter-domaines, qui permettent des transferts de données sécurisés entre domaines.
Les navigateurs modernes utilisent CORS dans un Conteneur API - tel que XMLHttpRequest ou Fetch - pour atténuer les risques de requêtes HTTP d'origines croisées.

Comment fonctionne la SCRO (Access-Control-Allow-Origin entête)

Wikipédia:

La norme CORS décrit les nouveaux en-têtes HTTP qui permettent aux navigateurs et aux serveurs de demander des URL distantes uniquement lorsqu'ils en ont l'autorisation.

Bien que certaines validations et autorisations puissent être effectuées par le serveur, c'est généralement la responsabilité du navigateur soutenir ces en-têtes et honorer les restrictions qu'ils imposent.

Exemple

  1. Le navigateur envoie le OPTIONS demande avec un Origin HTTP entête.

    La valeur de cet en-tête est le domaine qui a servi la page parente. Quand une page de http://www.example.com tente d'accéder aux données d'un utilisateur dans service.example.com, l'en-tête de requête suivant sera envoyé à service.example.com:

    Origine: http://www.example.com

  2. Le serveur à service.example.com peut répondre avec:

    • Un Access-Control-Allow-Origin (ACAO) dans sa réponse indiquant quels sites d'origine sont autorisés.
      Par exemple:

      Access-Control-Allow-Origin: http://www.example.com

    • Une page d'erreur si le serveur n'autorise pas la requête d'origine croisée

    • Un Access-Control-Allow-Origin (ACAO) en-tête avec un caractère générique qui autorise tous les domaines:

      Access-Control-Allow-Origin: *


33
2018-03-05 06:39



Si vous voulez simplement tester une application inter-domaine dans laquelle le navigateur bloque votre requête, vous pouvez simplement ouvrir votre navigateur en mode non sécurisé et tester votre application sans changer votre code et sans rendre votre code dangereux. Depuis MAC OS, vous pouvez le faire depuis la ligne de terminal:

open -a Google\ Chrome --args --disable-web-security --user-data-dir

8
2018-02-22 16:32



1. Un client télécharge le code javascript MyCode.js à partir de http: // siteA - l'origine.

Le code qui fait le téléchargement - votre tag de script html ou xhr de javascript ou autre - vient, disons, http: // siteZ. Et, lorsque le navigateur demande MyCode.js, il envoie un en-tête Origin: http: // siteZ", car il peut voir que vous demandez à siteA et siteZ! = siteA. (Vous ne pouvez pas arrêter ou interférer avec ceci.)

2. L'en-tête de réponse de MyCode.js contient Access-Control-Allow-Origin: http: // siteB, ce que je pensais signifier que MyCode.js était autorisé à faire des références d'origine croisée au site B.

non. Cela signifie que seul siteB est autorisé à faire cette demande. Donc, votre requête pour MyCode.js de siteZ reçoit une erreur à la place, et le navigateur ne vous donne généralement rien. Mais si vous faites revenir votre serveur A-C-A-O: siteZ à la place, vous obtiendrez MyCode.js. Ou si ça envoie '*', ça marchera, ça laissera tout le monde dedans. Ou si le serveur envoie toujours la chaîne de l'en-tête Origin: ... mais ... par sécurité, si vous avez peur des pirates , votre serveur ne doit autoriser que les origines sur une liste restreinte, qui sont autorisées à faire ces demandes.

Ensuite, MyCode.js vient de siteA. Quand il fait des demandes au siteB, ils sont tous d'origine croisée, le navigateur envoie Origin: siteA, et le siteB doit prendre le siteA, le reconnaître sur la liste restreinte des demandeurs autorisés, et renvoyer A-C-A-O: siteA. Ce n'est qu'alors que le navigateur laisse votre script obtenir le résultat de ces requêtes.


6
2018-02-27 01:37



je travaille avec express 4 et le nœud 7.4 et angulaire, j'ai eu le même problème moi aider cela:
  a) côté serveur: dans le fichier app.js je donne des en-têtes à toutes les réponses comme:

app.use(function(req, res, next) {  
      res.header('Access-Control-Allow-Origin', req.headers.origin);
      res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
      next();
 });  

cela doit avoir avant tout routeur.
J'ai vu beaucoup de ces en-têtes ajoutés:

res.header("Access-Control-Allow-Headers","*");
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');

mais je n'ai pas besoin de ça,
b) côté client: dans send ajax vous devez ajouter: "withCredentials: true," comme:

$http({
     method: 'POST',
     url: 'url, 
     withCredentials: true,
     data : {}
   }).then(function(response){
        // code  
   }, function (response) {
         // code 
   });

bonne chance.


5
2018-02-06 08:19



En utilisant Réagir et Axios, joignez le lien proxy à l'URL et ajoutez l'en-tête comme indiqué ci-dessous

https://cors-anywhere.herokuapp.com/ + Your API URL

Juste en ajoutant le lien de proxy fonctionnera, mais il peut également renvoyer l'erreur pour aucun accès. D'où mieux d'ajouter l'en-tête comme indiqué ci-dessous.

axios.get(`https://cors-anywhere.herokuapp.com/[YOUR_API_URL]`,{headers: {'Access-Control-Allow-Origin': '*'}})
      .then(response => console.log(response:data);
  }

5
2017-10-16 15:53



Si vous utilisez PHP, essayez d'ajouter le code suivant au début du fichier php:

Si vous utilisez localhost, essayez ceci:

header("Access-Control-Allow-Origin: *");

Si vous utilisez des domaines externes tels que le serveur, essayez ceci:

header("Access-Control-Allow-Origin: http://www.website.com");

4
2018-01-18 15:30



Pour le partage d'origine croisée, définissez l'en-tête: 'Access-Control-Allow-Origin':'*';

Php: header('Access-Control-Allow-Origin':'*');

Nœud: app.use('Access-Control-Allow-Origin':'*');

Cela permettra de partager du contenu pour un domaine différent.


3
2017-11-28 02:39