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 ceci:

  1. un client télécharge le code javascript MyCode.js de http://siteA - "151940920 de" l'origine .
  2. l'en-tête de réponse de MyCode.js contient Access-Control-Allow-Origin: http://siteB , ce qui veut dire MyCode.js a été autorisée à faire des références croisées au site B.
  3. le client déclenche certaines fonctionnalités de MyCode.js, qui à son tour font des demandes à http://siteB, ce qui devrait être bien, bien qu'il s'agisse de demandes d'origine croisée.

Eh bien, je me trompe. Il ne fonctionne pas comme ça à tout. Ainsi, j'ai lu "Cross-origin resource sharing et tenté de lire "Cross-Origin Resource Sharing" dans la recommandation du w3c

"

une chose est sûre - je le fais toujours Je ne comprends pas comment je suis censé utiliser cet en-tête.

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

P. S.

Je ne veux pas utiliser JSONP.

825
demandé sur Sujania 2012-05-17 17:23:54

11 réponses

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

lorsque le Site a tente de récupérer du contenu du Site B, Le Site B peut envoyer un en-tête de réponse Access-Control-Allow-Origin pour indiquer au navigateur que le contenu de cette page est accessible à certaines origines. (Un origine est un domaine, en plus d'un régime et le numéro de port .) Par défaut, les pages du Site B sont inaccessible à tout autre origine ; l'utilisation de l'en-tête Access-Control-Allow-Origin ouvre une porte pour l'accès d'origine croisée par Origine spécifique demandant.

pour chaque ressource/page que le Site B veut rendre accessible au Site A, le Site B doit servir ses pages avec l'en-tête de réponse:

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

les navigateurs modernes ne bloqueront pas complètement les requêtes trans-domaine. Si le Site a demande une page du Site B, le navigateur récupérera la page demandée sur le niveau de réseau et vérifier si les en-têtes de réponse liste le Site A comme un 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 l'événement XMLHttpRequest 's error et refusera les données de réponse au code JavaScript demandé.

Non de simples demandes

ce qui se passe au niveau du réseau peut être légèrement plus complexe que expliqué surtout. Si la requête est une "requête non simple , le navigateur envoie d'abord une requête D'OPTIONS" preflight "sans données, pour vérifier que le serveur acceptera la requête. Une requête n'est pas simple lorsque soit (soit les deux):

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

si le serveur répond aux OPTIONS pré-Light avec les en-têtes de réponse appropriés ( Access-Control-Allow-Headers pour les en-têtes non simples, Access-Control-Allow-Methods pour les verbes non simples) qui correspondent au verbe non simple et / ou non simple les en-têtes, puis le navigateur envoie la demande réelle.

en supposant que le Site a veut envoyer une demande PUT pour /somePage , avec une valeur non-simple Content-Type de application/json , le navigateur enverrait d'abord une demande preflight:

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. Cette option preflight 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 réelle (après que le pré-vol est fait), le comportement est identique à la façon dont une requête simple est traitée. En d'autres termes, une requête non simple dont le pré-lancement est réussi est traitée de la même manière qu'une requête simple (c'est-à-dire que le serveur doit encore envoyer Access-Control-Allow-Origin pour la réponse réelle).

les navigateurs envoient la requête réelle:

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 , juste comme pour une simple requête:

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

Voir Compréhension XMLHttpRequest au cours de la SCRO pour un peu plus d'informations à propos de la non-simple demande.

1060
répondu apsillers 2017-05-23 11:47:28

Cross-Origin Request Sharing - CORS (A. K. A. Cross-Domain AJAX request) est un problème que la plupart des développeurs web peuvent rencontrer, selon Same-Origin-Policy, les navigateurs restreindre JavaScript client dans un bac à sable de sécurité, généralement JS ne peut pas communiquer directement avec un serveur distant à partir d'un domaine différent. Dans le passé, les développeurs ont créé de nombreuses façons délicates de réaliser des requêtes de ressources inter-domaines, le plus souvent en utilisant des moyens sont:

  1. utiliser Flash/Silverlight ou côté serveur comme un "proxy" pour communiquer avec la télécommande.
  2. JSON With Padding ( JSONP ).
  3. intègre un serveur distant dans une iframe et communique par fragment ou fenêtre.nom, se référer ici .

ces façons délicates ont plus ou moins certains problèmes, par exemple JSONP pourrait entraîner un trou de sécurité si les développeurs simplement "eval" it, et #3 ci-dessus, bien que cela fonctionne, les deux domaines devraient construire contrat strict entre eux, il ni souple ni élégant IMHO:)

le W3C avait introduit le partage des ressources Multi-origines (CORS) comme solution standard pour fournir une façon sûre, flexible et standard recommandée de résoudre ce problème.

Le Mécanisme

D'un haut niveau, nous pouvons simplement considérer que CORS est un contrat entre client AJAX appel du domaine A et une page hébergée sur le domaine B, une requête/réponse Type À origine croisée serait:

DomainA AJAX en-têtes de requête

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 

DomainB en-têtes de réponse

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 I ci-dessus étaient les faits principaux," L'en-tête de la demande "Origine" indique l'origine de la demande d'origine croisée ou de la demande avant le vol", "le contrôle D'accès-Autoriser-origine"." l'en-tête de réponse indique que cette page permet la requête à distance à partir de DomainA (si la valeur est * indiquer permet les requêtes à distance à partir de n'importe quel domaine).

comme je l'ai mentionné ci-dessus, W3 a recommandé le navigateur pour mettre en œuvre une" "demande pré-vol "avant de soumettre la demande HTTP réellement Cross-Origin, en un mot il s'agit D'une demande HTTP OPTIONS :

OPTIONS DomainB.com/foo.aspx HTTP/1.1

Si foo.aspx supporte les OPTIONS HTTP verb, il peut renvoyer la 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

seulement si la réponse contient" Access-Control-Allow-Origin "et sa valeur est" * " ou contient le domaine qui a soumis la demande CORS, en satisfaisant à cette condition de mandtory le navigateur soumettra la demande transversale réelle de domaine, et cache le résultat dans " Preflight-Result-Cache ".

j'ai blogué sur CORS il y a trois ans: AJAX Cross-Origin HTTP request

104
répondu Wayne Ye 2016-07-28 09:01:23

Question est un peu trop vieux pour répondre, mais je poste ceci pour toute référence future à cette question.

selon ce article de Mozilla Developer Network,

une ressource fait une requête HTTP d'origine croisée lorsqu'elle demande une ressource à partir d'un domaine ou d'un port différent de celui que la première ressource elle-même sert.

enter image description here

Un page HTML servi de http://domain-a.com prend un <img> src demande de http://domain-b.com/image.jpg .

De nombreuses pages sur le web aujourd'hui chargent des ressources comme CSS stylesheets , images et scripts de domaines séparés (donc il devrait être cool).

Politique De La Même Origine

pour des raisons de sécurité, les navigateurs restreignent origine croisée HTTP requests initiated from within scripts .

Par exemple, XMLHttpRequest et Fetch suivent la Politique de même origine .

Ainsi, une application web utilisant XMLHttpRequest ou Fetch ne pouvait faire que requêtes HTTP à son propre domaine .

Cross-Origin Resource Sharing (CORS)

pour améliorer les applications web, les développeurs ont demandé aux fournisseurs de navigateur pour autoriser les requêtes de domaine.

Le Cross-Origin Resource sharing (SCRO) mécanisme donne des serveurs web cross-domaine des contrôles d'accès , qui permet de sécuriser la croix-domaine des transferts de données.

Les navigateurs modernes utilisez CORS dans un conteneur API - tels que XMLHttpRequest ou Fetch - pour atténuer les risques de demandes HTTP d'origine croisée.

Comment la SCRO œuvres ( Access-Control-Allow-Origin en-tête)

Wikipedia :

la norme CORS décrit les nouveaux en-têtes HTTP qui fournissent aux navigateurs et aux serveurs une façon de demander des URL distantes uniquement lorsqu'ils en ont la permission.

bien qu'une validation et une autorisation puissent être effectuées par le serveur, il est généralement de la responsabilité du navigateur de soutenir ces en-têtes et d'honorer les restrictions qu'ils imposent.

exemple

  1. le navigateur envoie la demande OPTIONS avec un en-tête Origin HTTP .

    la valeur de cet en-tête est domaine qui a servi à la page mère. Lorsqu'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 serait envoyé à service.example.com :

    origine: http://www.example.com

  2. le serveur à service.example.com peut répondre par:

    • an Access-Control-Allow-Origin (ACAO) en-tête dans sa réponse indiquant sites d'origine sont autorisées.

      Par exemple:

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

    • une page d'erreur si le serveur ne permet pas la requête d'origine croisée

    • Un Access-Control-Allow-Origin (ACAO) de la tête avec un joker qui permet à tous les domaines:

      Access-Control-Allow-Origin: *

35
répondu Trix 2017-03-05 06:39:53

si vous voulez juste tester une application de domaine croisé dans laquelle le navigateur bloque votre demande, alors vous pouvez juste ouvrir votre navigateur en mode non sécuritaire et tester votre application sans changer votre code et sans rendre votre code dangereux. De MAC OS vous pouvez le faire à partir de la ligne de terminal:

open -a Google\ Chrome --args --disable-web-security --user-data-dir
7
répondu Maurizio Brioschi 2017-02-22 16:32:30

utilisant React et Axios , joindre le lien proxy à L'URL et ajouter l'en-tête comme montré ci-dessous

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

simplement en ajoutant le lien Proxy fonctionnera, mais il peut aussi lancer une erreur pour aucun accès à nouveau. Il est donc préférable 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);
  }
7
répondu Dhaval Jardosh 2017-10-16 15:53:24

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

le code qui fait le téléchargement-votre étiquette de script html ou xhr à partir de javascript ou autre - vient de, disons, http://siteZ . Et, quand le navigateur demande MyCode.js, il envoie une origine: en-tête disant "origine: http://siteZ ", parce qu'il peut voir que vous demandez à siteA et à siteZ != siteA. (Vous ne pouvez pas arrêter ou interférer avec ce.)

2. L'en-tête de réponse de MyCode.js contains Access-Control-Allow-Origin: http://siteB , ce qui veut dire MyCode.js a été autorisée à faire des références croisées au site B.

pas de. Cela signifie que seul siteB est autorisé à faire cette demande. Donc votre demande pour MyCode.js de siteZ obtient une erreur à la place, et le navigateur généralement vous donne 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 entrer. Ou si le serveur envoie toujours la chaîne depuis L'en-tête Origin:... mais... pour la sécurité, si vous avez peur des hackers, votre serveur ne devrait autoriser que les origines sur une liste restreinte, qui sont autorisées à faire ces requêtes.

Alors, MyCode.js vient de siteA. Quand il fait des demandes à siteB, ils sont tout d'origine croisée, le navigateur envoie Origin: siteA, et siteB doit prendre le siteA, reconnaître qu'il est sur la courte liste des demandeurs autorisés, et renvoyer A-C-A-O: siteA. Alors seulement, le navigateur laissez votre script obtenez le résultat de ces demandes.

6
répondu OsamaBinLogin 2016-02-27 01:37:43

je travaille avec express 4 et node 7.4 et angular, j'ai eu le même problème que me aider à ceci:

a) côté serveur:dans l'application file.js-je donner des en-têtes à toutes les réponse du genre:

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 ajouter ces en-têtes:

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 que,

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
répondu izik f 2017-02-06 08:19:11

chaque fois que je commence à penser à CORS, mon intuition sur le site qui héberge les en-têtes est incorrecte, tout comme vous l'avez décrit dans votre question. Pour moi, cela aide de penser au but de la même politique d'origine.

le but de la même politique d'origine est de vous protéger contre le JavaScript malveillant sur siteA.com accès à des renseignements personnels que vous avez choisi de partager seulement avec siteB.com. Sans la même politique d'origine, JavaScript écrit par les auteurs de siteA.com pourrait faire votre navigateur faire des demandes à siteB.com, en utilisant vos cookies d'authentification pour siteB.com. De cette façon, siteA.com pourrait voler les informations secrètes que vous partagez avec siteA.com.

il faut parfois travailler le cross domain, c'est là que CORS intervient. CORS assouplit la même politique d'origine pour domainA.com, en utilisant l'en-tête Access-Control-Allow-Origin pour lister d'autres domaines (domainB.com) qui sont fiables pour exécuter JavaScript qui peut interagir avec domainA.com.

pour comprendre quel domaine devrait servir les en-têtes CORS, considérez ceci. Vous visitez malicious.com, qui contient du JavaScript qui essaie de faire une requête de domaine croisée mybank.com. Il devrait être jusqu'à mybank.com, pas malicious.com, pour décider si oui ou non il fixe des en-têtes CORS qui assouplissent la même politique d'origine permettant le JavaScript de malicious.com pour interagir avec elle. Si c'était possible pour malicous.com pour configurer ses propres en-têtes CORS permettant son propre accès JavaScript à mybank.com, cela annulerait complètement la même politique d'origine.

je pense que la raison de ma mauvaise intuition est le point de vue que j'ai lors du développement d'un site. Son mon site, avec tous mon JavaScript, donc il ne fait rien de malveillant et il devrait être jusqu'à me pour préciser quels autres sites mon JavaScript peut interagir avec. Alors qu'en fait je devrais être pensez-vous que autres sites JavaScript tentent d'interagir avec mon site et devrais-je utiliser CORS pour leur permettre?

5
répondu Dom 2018-01-28 18:47:01

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 server, essayez ceci:

header("Access-Control-Allow-Origin: http://www.website.com");
3
répondu Melvin Guerrero 2017-01-18 15:30:06

pour le partage d'origine croisée, en-tête de série: 'Access-Control-Allow-Origin':'*';

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

noeud: app.use('Access-Control-Allow-Origin':'*');

cela permettra de partager du contenu pour différents domaines.

2
répondu user2923052 2017-01-16 08:10:04

en Python j'ai utilisé la Flask-CORS bibliothèque avec un grand succès. Cela rend traiter avec CORS super facile et indolore. J'ai ajouté du code à partir de la documentation de la bibliothèque ci-dessous.

installation:

$ pip install -U flask-cors

exemple Simple qui permet des CORS pour tous les domaines sur toutes les routes:

from flask import Flask
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

@app.route("/")
def helloWorld():
  return "Hello, cross-origin-world!"

pour des exemples plus précis, voir la documentation. J'ai utilisé l'exemple simple ci-dessus pour contourner la question de CORS dans une application ionique je construis qui doit accéder à un serveur flasque séparé.

2
répondu agaidis 2018-01-25 11:10:18