Apparemment, j'ai complètement mal compris sa sémantique. J'ai pensé à quelque chose comme ça:
Eh bien, je me trompe. Cela ne marche pas du tout comme ça. Donc, j'ai lu Partage de ressources d'origine croisée et j'ai essayé de lire Partage de ressources d'origine croisée dans la recommandation w3c
Une chose est sûre: je ne comprends toujours 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 à l'aide de cet en-tête?
P.S.
Je ne veux pas utiliser JSONP.
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 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 , ainsi qu'un schéma et un numéro de port .) Par défaut, les pages du site B sont inaccessibles à toute autre origine ; L'utilisation de l'en-tête Access-Control-Allow-Origin
ouvre une porte d'accès croisé entre origines requérantes spécifiques.
Pour chaque ressource/page que le site B souhaite rendre accessible au site A, le site B doit afficher 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 interdomaines. Si le site A demande une page au site B, le navigateur récupérera la page demandée au niveau du réseau} _ et vérifiera si les en-têtes de réponse répertorient le site A en tant que domaine demandeur autorisé. Si le site B n'a pas indiqué que le site A est autorisé à accéder à cette page, le navigateur déclenche l'événement XMLHttpRequest
's error
et refuse les données de réponse au code JavaScript demandeur.
Ce qui se passe au niveau du réseau peut être légèrement plus complexe que celui expliqué ci-dessus. Si la demande est une demande "non simple" , le navigateur envoie d'abord une demande OPTIONS sans contrôle de données, afin de vérifier que le serveur accepte la demande. Une demande n'est pas simple lorsque l'une ou l'autre (ou les deux):
Accept
Accept-Language
Content-Language
Content-Type
(ceci n'est simple que lorsque sa valeur est application/x-www-form-urlencoded
, multipart/form-data
ou text/plain
)Si le serveur répond au contrôle en amont des 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-Methods
pour les verbes non simples) correspondant aux en-têtes non simples et/ou non simples, le navigateur envoie la demande réelle.
En supposant que le site A souhaite envoyer une demande PUT pour /somePage
, avec une valeur non-simple Content-Type
de application/json
, le navigateur enverra 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 des options obtient les en-têtes de réponse réussie:
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 demande réelle (après le contrôle en amont), le comportement est identique à la manière dont une demande simple est traitée. En d’autres termes, une requête non simple dont le contrôle en amont a réussi est traitée de la même manière qu’une requête simple (c’est-à-dire que le serveur doit toujours envoyer à nouveau Access-Control-Allow-Origin
pour la réponse réelle).
Les navigateurs envoient la demande 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
, comme pour une simple requête:
Access-Control-Allow-Origin: http://siteA.com
Voir Comprendre XMLHttpRequest sur CORS pour un peu plus d'informations sur les requêtes non simples.
Le partage de requêtes entre plusieurs origines - CORS
(demande AKA entre plusieurs domaines AJAX) est un problème que la plupart des développeurs Web pourraient rencontrer. Selon Same-Origin-Policy, les navigateurs restreignent le code JavaScript du client dans un sandbox de sécurité. En général, JS ne peut pas le faire directement. communiquer avec un serveur distant d'un autre domaine. Auparavant, les développeurs créaient de nombreuses méthodes délicates pour répondre aux demandes de ressources inter-domaines, notamment:
Ces solutions compliquées présentent plus ou moins quelques problèmes. Par exemple, JSONP risque de créer une faille de sécurité si les développeurs la "valident" simplement et n ° 3 ci-dessus. Bien que cela fonctionne, les deux domaines doivent établir un contrat strict entre eux, sans souplesse ni élégance. A MON HUMBLE AVIS:)
Le W3C a introduit le partage de ressources d'origine croisée (CORS) en tant que solution standard pour fournir un moyen standard sûr et flexible et recommandé de résoudre ce problème.
Le mécanisme
A un niveau élevé, nous pouvons simplement considérer que CORS est un contrat entre un appel client AJAX du domaine A et une page hébergée sur le domaine B, une demande/réponse typique de Cross-Origin serait:
DomainA AJAX en-têtes de demande
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 que j’ai marquées ci-dessus étaient des faits essentiels, l’en-tête de requête "Origine" indique l’origine de la demande de contrôle de contrôle ou de contrôle en provenance de l'origine ", l'en-tête de réponse" Contrôle d'accès-autorisation-d'origine "indique que cette page autorise la demande à distance DomainA (si la valeur est *, indiquez si vous autorisez les requêtes distantes depuis n'importe quel domaine).
Comme je l'ai mentionné plus haut, W3 a recommandé au navigateur d'implémenter une "requête preflight" avant de soumettre la requête HTTP véritablement d'origine croisée. En bref, il s'agit d'une requête HTTP OPTIONS
:
OPTIONS DomainB.com/foo.aspx HTTP/1.1
Si foo.aspx prend en charge 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
Seulement si la réponse contient "Access-Control-Allow-Origin" ET si sa valeur est "*" ou contient le domaine qui a soumis la demande CORS, en satisfaisant cette condition obligatoire, le navigateur soumettra la demande réelle à plusieurs domaines et mettra en cache le résultat. dans "Preflight-Result-Cache".
J'ai blogué à propos de CORS il y a trois ans: AJAX Requête HTTP Cross-Origin
La question est un peu trop ancienne pour y répondre, mais je la poste pour toute référence future à cette question.
Selon this article de Mozilla Developer Network,
Une ressource crée une requête HTTP multi-origine lorsqu'elle demande une ressource à un domaine ou à un port différent de celui que la première ressource sert elle-même.
Un page HTML servi depuis http://domain-a.com
fait une demande src <img>
pour http://domain-b.com/image.jpg
.
Aujourd'hui, de nombreuses pages Web chargent des ressources telles que feuilles de style CSS, images et scripts à partir de domaines distincts (cela devrait donc être cool).
Pour des raisons de sécurité, les navigateurs limitent les HTTP d'origine croisée _ requêtes initiées à partir de scripts.
Par exemple, XMLHttpRequest
et Fetch
suivent la règle de même origine.
Ainsi, une application Web utilisant XMLHttpRequest
ou Fetch
ne peut que rendre requêtes HTTP à son propre domaine.
Pour améliorer les applications Web, les développeurs ont demandé aux fournisseurs de navigateurs d'autoriser les requêtes interdomaines.
Le mécanisme CORS) donne aux serveurs Web contrôles d'accès entre domaines, qui permettent des transferts de données entre domaines sécurisés.
Les navigateurs modernes utilisent CORS dans un conteneur d'API - tel que XMLHttpRequest
ou Fetch
- pour atténuer les risques liés aux requêtes HTTP d'origine croisée.
Access-Control-Allow-Origin
)La norme CORS décrit les nouveaux en-têtes HTTP qui fournissent aux navigateurs et aux serveurs un moyen de demander des URL distantes uniquement lorsqu'ils disposent de l'autorisation.
Bien que certaines validations et autorisations puissent être effectuées par le serveur, c'est généralement la responsabilité du navigateur de prendre en charge ces en-têtes et de respecter les restrictions qu'ils imposent.
Le navigateur envoie la demande OPTIONS
avec un en-tête Origin HTTP
.
La valeur de cet en-tête est le domaine qui a servi la page parent. 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 est envoyé à service.example.com
:
Origine: http://www.example.com
Le serveur à service.example.com
peut répondre avec:
Un en-tête Access-Control-Allow-Origin
(ACAO) dans sa réponse indiquant les sites d'origine autorisés.
Par exemple:
Access-Control-Allow-Origin: http://www.example.com
Une page d'erreur si le serveur n'autorise pas la demande d'origine croisée
Un en-tête Access-Control-Allow-Origin
(ACAO) avec un caractère générique qui autorise tous les domaines:
Access-Control-Allow-Origin: *
En utilisant React et Axios , joignez un lien proxy à l’URL et ajoutez un en-tête comme indiqué ci-dessous
https://cors-anywhere.herokuapp.com/
+ Your API URL
Simplement en ajoutant le lien Proxy fonctionnera, mais il peut également renvoyer une erreur pour No Access à nouveau. Il est donc préférable d’ajouter un 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);
}
Si vous souhaitez simplement tester une application inter-domaines dans laquelle le navigateur bloque votre demande, vous pouvez simplement ouvrir votre navigateur en mode non sécurisé et tester votre application sans modifier votre code ni rendre votre code non sécurisé. peut le faire depuis la ligne de terminal:
open -a Google\ Chrome --args --disable-web-security --user-data-dir
Chaque fois que je commence à penser à CORS, mon intuition quant au site qui héberge les en-têtes est incorrecte, tout comme vous l'avez décrit dans votre question. Pour moi, il est utile de réfléchir à l'objectif de la même politique d'origine.
L'objectif de la même stratégie Origin est de vous protéger contre le JavaScript malveillant sur siteA.com qui accède aux informations privées que vous avez choisi de partager uniquement avec siteB.com. Sans la même politique d'origine, les auteurs JavaScript de JavaScript rédigés par les auteurs de siteA.com pourraient demander à votre navigateur de demander à siteB.com, à l'aide de vos cookies d'authentification pour siteB.com. De cette manière, siteA.com pourrait voler les informations secrètes que vous partagez avec siteB.com.
Parfois, vous devez travailler sur plusieurs domaines, c'est là que CORS entre en jeu. CORS assouplit la même stratégie d'origine pour domainA.com, en utilisant l'en-tête Access-Control-Allow-Origin
pour répertorier les autres domaines (domainB.com) autorisés à exécuter JavaScript et pouvant interagir avec domainA .com.
Pour comprendre quel domaine doit servir les en-têtes CORS, considérez ceci. Vous visitez le site malveillant.com, qui contient du code JavaScript qui tente d'envoyer une requête interdomaine à mybank.com. Il appartient à mybank.com, et non à malware.com, de décider s’il définit ou non les en-têtes CORS qui assouplissent la même stratégie Origin permettant au JavaScript de malveillant.com d’interagir avec lui. Si malicous.com pouvait définir ses propres en-têtes CORS autorisant 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. C'est mon site, avec tout mon JavaScript, donc il ne fait rien de malveillant et il devrait incomber à moi de spécifier avec quels autres sites mon JavaScript peut interagir avec . Quand, en fait, je devrais penser quels autres sites JavaScript essaient d'interagir avec mon site et devrais-je utiliser CORS pour les autoriser?
1. Un client télécharge le code javascript MyCode.js depuis http: // siteA - the Origin.
Le code qui effectue le téléchargement - votre balise de script html ou xhr à partir de javascript ou autre - provient de, disons, http: // siteZ . Et, lorsque le navigateur demande MyCode.js, il envoie un en-tête Origin: "Origin: http: // siteZ ", car il peut voir que vous demandez à siteA et siteZ! = SiteA. (Vous ne pouvez pas arrêter ou interférer avec cela.)
2. L'en-tête de réponse de MyCode.js contient Access-Control-Allow-Origin: http: // siteB , ce qui, à mon avis, signifiait que MyCode.js était autorisé à faire des références croisées au site B .
non. Cela signifie que seul le site B est autorisé à effectuer cette demande. Donc, votre demande de MyCode.js auprès de siteZ obtient une erreur et le navigateur ne vous donne généralement rien. Mais si vous faites que votre serveur retourne A-C-A-O: siteZ à la place, vous obtiendrez MyCode.js. Ou si elle envoie '*', cela fonctionnera, cela 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 craignez les pirates , votre serveur ne doit autoriser que les origines de la liste restreinte, qui sont autorisées à effectuer ces demandes.
Ensuite, MyCode.js provient du siteA. Lorsqu'ils adressent des demandes à siteB, ils sont tous inter-origines, le navigateur envoie Origin: siteA et siteB doit prendre le siteA, le reconnaître sur la liste des demandeurs autorisés et renvoyer A-C-A-O: siteA. Ce n’est qu’alors que le navigateur laissera à votre script le résultat de ces requêtes.
je travaille avec express 4 et noeud 7.4 et angulaire, j'ai eu le même problème moi aider ceci:
a) côté serveur: dans le fichier app.js, je donne des en-têtes à toutes les réponses telles que:
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 d'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.
Si vous utilisez PHP, essayez d'ajouter le code suivant à la fin du fichier php:
si vous utilisez localhost, essayez ceci:
header("Access-Control-Allow-Origin: *");
si vous utilisez des domaines externes tels que serveur, essayez ceci:
header("Access-Control-Allow-Origin: http://www.website.com");
Pour le partage d'origine croisée, définissez l'en-tête: 'Access-Control-Allow-Origin':'*';
Php: header('Access-Control-Allow-Origin':'*');
Node: app.use('Access-Control-Allow-Origin':'*');
Cela permettra de partager du contenu pour différents domaines.
En Python, j'utilise la bibliothèque Flask-CORS
avec beaucoup de succès. Cela rend la négociation avec CORS super facile et sans douleur. J'ai ajouté du code provenant de la documentation de la bibliothèque ci-dessous.
Installation:
$ pip install -U flask-cors
Exemple simple permettant à CORS de gérer tous les domaines et 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 spécifiques, voir la documentation. J'ai utilisé l'exemple simple ci-dessus pour résoudre le problème de la CORS dans une application ionique que je construis et qui doit accéder à un serveur de flacon séparé.
L'en-tête de réponse Access-Control-Allow-Origin indique si le la réponse peut être partagée avec le code demandeur provenant de l'origine donnée.
Header type Response header
Forbidden header name no
Une réponse qui indique au navigateur d'autoriser le code provenant de n'importe quelle origine à accéder à une ressource comprendra les éléments suivants:
Access-Control-Allow-Origin: *
Pour plus d'informations, visitez ici ....
Collez simplement le code suivant dans votre fichier web.config.
Notez que vous devez coller le code suivant sous la balise <system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
</customHeaders>
</httpProtocol>