Je voulais créer un wiki communautaire sur HTML/JS règles de même origine pour aider, espérons-le, tous ceux qui recherchent ce sujet. C’est l’un des sujets les plus recherchés sur SO et il n’existe pas de wiki consolidé, alors je vais y aller :)
La même stratégie d'origine empêche un document ou un script chargé à partir d'une origine d'obtenir ou de définir les propriétés d'un document provenant d'une autre origine. Cette politique remonte à Netscape Navigator 2.0.
S'il vous plaît, gardez les exemples commentés et liez de préférence vos sources.
document.domain
Notez qu'il s'agit d'une méthode iframe qui définit la valeur de document.domain sur un suffixe du domaine actuel. Si tel est le cas, le domaine le plus court est utilisé pour les contrôles Origin ultérieurs. Par exemple, supposons qu'un script du document sous http://store.company.com/dir/other.html
exécute l'instruction suivante:
document.domain = "company.com";
Une fois cette instruction exécutée, la page passera la vérification de l'origine avec http://company.com/dir/page.html
. Toutefois, selon le même raisonnement, company.com ne pouvait pas définir document.domain
sur othercompany.com
.
Avec cette méthode, vous seriez autorisé à exécuter du javascript à partir d'un iframe provenant d'un sous-domaine d'une page provenant du domaine principal. Cette méthode ne convient pas aux ressources inter-domaines car des navigateurs tels que Firefox ne vous permettront pas de changer le document.domain
en un domaine complètement étranger.
Source: https://developer.mozilla.org/en/Same_Origin_policy_for_JavaScript
Partage de ressources d'origine croisée (CORS) est un brouillon de travail du W3C qui définit la manière dont le navigateur et le serveur doivent communiquer pour accéder aux sources de différentes origines. L'idée de base de CORS est d'utiliser des en-têtes HTTP personnalisés pour permettre au navigateur et au serveur de se connaître suffisamment pour déterminer si la demande ou la réponse doit réussir ou échouer.
Pour une requête simple, utilisant GET
ou POST
sans en-tête personnalisé et dont le corps est text/plain
, la demande est envoyée avec un en-tête supplémentaire appelé Origin
. L'en-tête Origin contient l'origine (protocole, nom de domaine et port) de la page demandée afin que le serveur puisse facilement déterminer s'il doit ou non répondre à une réponse. Un exemple d'en-tête Origin
pourrait ressembler à ceci:
Origin: http://www.stackoverflow.com
Si le serveur décide que la demande doit être autorisée, il envoie un en-tête Access-Control-Allow-Origin
renvoyant la même origine que celle envoyée ou *
s'il s'agit d'une ressource publique. Par exemple:
Access-Control-Allow-Origin: http://www.stackoverflow.com
Si cet en-tête est manquant ou si les origines ne correspondent pas, le navigateur refuse la demande. Si tout va bien, le navigateur traite la demande. Notez que ni les demandes ni les réponses n'incluent d'informations de cookie.
L'équipe de Mozilla suggère dans leur article sur CORS que vous devriez vérifier l'existence de la propriété withCredentials
pour déterminer si le navigateur prend en charge CORS via XHR. Vous pouvez ensuite coupler avec l'existence de l'objet XDomainRequest
pour couvrir tous les navigateurs:
function createCORSRequest(method, url){
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr){
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined"){
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
xhr = null;
}
return xhr;
}
var request = createCORSRequest("get", "http://www.stackoverflow.com/");
if (request){
request.onload = function() {
// ...
};
request.onreadystatechange = handler;
request.send();
}
Notez que pour que la méthode CORS fonctionne, vous devez avoir accès à tout type de mécanisme d'en-tête de serveur et ne pas accéder simplement à une ressource tierce.
Source: http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-Origin-resource-sharing/
window.postMessage
window.postMessage
, lorsqu'il est appelé, provoque l'envoi d'une MessageEvent
dans la fenêtre cible lorsqu'un script en attente à exécuter est terminé (par exemple, les gestionnaires d'événement restants si window.postMessage
est appelé à partir d'un gestionnaire d'événement, les délais d’attente précédemment définis, etc.). La MessageEvent
a le type de message, une propriété data
qui est définie sur la valeur de chaîne du premier argument fourni à window.postMessage
, une propriété Origin
correspondant à l'origine du document principal dans la fenêtre appelant window.postMessage
au moment où window.postMessage
a été appelé, et une propriété source
qui est la fenêtre à partir de laquelle window.postMessage
est appelé.
Pour utiliser window.postMessage
, un écouteur d'événement doit être associé:
// Internet Explorer
window.attachEvent('onmessage',receiveMessage);
// Opera/Mozilla/Webkit
window.addEventListener("message", receiveMessage, false);
Et une fonction receiveMessage
doit être déclarée:
function receiveMessage(event)
{
// do something with event.data;
}
L'iframe hors site doit également envoyer les événements correctement via postMessage
:
<script>window.parent.postMessage('foo','*')</script>
Toute fenêtre peut accéder à cette méthode sur n’importe quelle autre fenêtre, à tout moment, quel que soit l’emplacement du document dans la fenêtre, pour lui envoyer un message. Par conséquent, tout écouteur d'événements utilisé pour recevoir des messages doit d'abord vérifier l'identité de l'expéditeur du message, en utilisant les propriétés Origin et éventuellement source. Cela ne peut pas être sous-estimé: L'échec de la vérification des propriétés Origin
et éventuellement source
active les attaques de script entre sites.
Source: https://developer.mozilla.org/en/DOM/window.postMessage
Configurer un simple proxy inverse sur le serveur permettra au navigateur d’utiliser des chemins relatifs pour les requêtes Ajax, alors que le serveur agirait comme un proxy vers n’importe quel emplacement distant.
Si vous utilisez mod_proxy dans Apache, la directive de configuration fondamentale pour configurer un proxy inverse est le ProxyPass
. Il est généralement utilisé comme suit:
ProxyPass /ajax/ http://other-domain.com/ajax/
Dans ce cas, le navigateur pourrait demander /ajax/web_service.xml
en tant qu'URL relative, mais le serveur le servirait en agissant en tant que proxy pour http://other-domain.com/ajax/web_service.xml
.
Une caractéristique intéressante de cette méthode est que le proxy inverse peut facilement répartir les requêtes vers plusieurs serveurs principaux, agissant ainsi comme un équilibreur de charge .
J'utilise JSONP.
Fondamentalement, vous ajoutez
<script src="http://..../someData.js?callback=some_func"/>
sur ta page.
some_func () devrait être appelé pour que vous soyez averti que les données sont dans.
AnyOrigin ne fonctionnait pas bien avec certains sites https, alors je viens d'écrire une alternative open source appelée quel que soit l'origine du projet qui semble bien fonctionner avec https.
Je ne peux pas prétendre au crédit de cette image, mais elle correspond à tout ce que je sais à ce sujet et offre un peu d'humour en même temps.
Le moyen le plus récent de surmonter la politique de même origine que j'ai trouvée est http://anyorigin.com/
Le site est fait pour que vous lui donniez n'importe quelle URL et qu'il génère un code javascript/jquery qui vous permet d'obtenir le code HTML/les données, indépendamment de l'origine. En d'autres termes, toute URL ou page Web est une requête JSONP.
Je l'ai trouvé très utile :)
Voici un exemple de code javascript de anyorigin:
$.getJSON('http://anyorigin.com/get?url=google.com&callback=?', function(data){
$('#output').html(data.contents);
});
JSONP me vient à l’esprit:
JSONP ou "JSON avec remplissage" est un complément au format de données JSON de base, un modèle d'utilisation permettant à une page de demander et d'utiliser de manière plus significative JSON à partir d'un serveur autre que le serveur principal. JSONP est une alternative à une méthode plus récente appelée Partage de ressources d'origine croisée.
Eh bien, j’ai utilisé curl dans PHP pour contourner cela. J'ai un service Web sur le port 82.
<?php
$curl = curl_init();
$timeout = 30;
$ret = "";
$url="http://localhost:82/put_val?val=".$_GET["val"];
curl_setopt ($curl, CURLOPT_URL, $url);
curl_setopt ($curl, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt ($curl, CURLOPT_MAXREDIRS, 20);
curl_setopt ($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5");
curl_setopt ($curl, CURLOPT_CONNECTTIMEOUT, $timeout);
$text = curl_exec($curl);
echo $text;
?>
Voici le javascript qui appelle le fichier PHP
function getdata(obj1, obj2) {
var xmlhttp;
if (window.XMLHttpRequest)
xmlhttp=new XMLHttpRequest();
else
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("txtHint").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","phpURLFile.php?eqp="+obj1+"&val="+obj2,true);
xmlhttp.send();
}
Mon code HTML fonctionne sous WAMP dans le port 80. Nous y voilà, la même politique d'origine a été contournée :-)
Cette analyse à peu près ce qui est disponible là-bas: http://www.slideshare.net/SlexAxton/breaking-the-cross-domain-barrier
Pour la solution postMessage, consultez:
https://github.com/chrissrogers/jquery-postmessage/blob/master/jquery.ba-postmessage.js
et une version légèrement différente:
https://github.com/thomassturm/ender-postmessage/blob/master/ender-postmessage.js
Personnellement, window.postMessage
est le moyen le plus fiable que j'ai trouvé pour les navigateurs modernes. Vous devez faire un peu plus de travail pour vous assurer de ne pas vous laisser faire face aux attaques XSS, mais c'est un compromis raisonnable.
Il existe également plusieurs plugins pour les kits d’outils Javascript populaires qui encapsulent window.postMessage
et fournissent des fonctionnalités similaires aux navigateurs plus anciens en utilisant les autres méthodes décrites ci-dessus.
Voici quelques solutions de contournement et explication de la même politique d'origine:
Thiru's Blog - Solution de contournement de la stratégie d'origine du navigateur