Konzept: Solange Protokoll, Domänenname und Port unterschiedlich sind, werden sie als unterschiedliche Domänen betrachtet.
URL 说明 是否允许通信 http://www.a.com/a.js http://www.a.com/b.js 同一域名下 允许 http://www.a.com/lab/a.js http://www.a.com/script/b.js 同一域名下不同文件夹 允许 http://www.a.com:8000/a.js http://www.a.com/b.js 同一域名,不同端口 不允许 http://www.a.com/a.js https://www.a.com/b.js 同一域名,不同协议 不允许 http://www.a.com/a.js http://70.32.92.74/b.js 域名和域名对应ip 不允许 http://www.a.com/a.js http://script.a.com/b.js 主域相同,子域不同 不允许 http://www.a.com/a.js http://a.com/b.js 同一域名,不同二级域名(同上) 不允许(cookie这种情况下也不允许访问) http://www.cnblogs.com/a.js http://www.a.com/b.js 不同域名 不允许
Unterschiede in Ports und Protokollen können nur im Hintergrund gelöst werden.
CORS(Cross-Origin Resource Sharing
) Cross-Domain Resource Sharing definiert, wie Browser und Server beim Zugriff auf domänenübergreifende Ressourcen kommunizieren sollen. Die Grundidee hinter CORS
besteht darin, benutzerdefinierte HTTP-Header zu verwenden, um dem Browser die Kommunikation mit dem Server zu ermöglichen, um zu bestimmen, ob die Anfrage oder Antwort erfolgreich sein soll oder fehlschlagen soll.
<script type="text/javascript"> var xhr = new XMLHttpRequest(); xhr.open("GET", "/trigkit4",true); xhr.send(); </script>
Das obige trigkit4
ist ein relativer Pfad. Wenn wir CORS
verwenden möchten, könnte der entsprechende Ajax
-Code so aussehen:
<script type="text/javascript"> var xhr = new XMLHttpRequest(); xhr.open("GET", "http://segmentfault.com/u/trigkit4/",true); xhr.send(); </script>
Der Unterschied zwischen dem Code und dem vorherigen Der Grund dafür ist, dass der relative Pfad durch den absoluten Pfad anderer Domänen ersetzt wird. Dies ist die Schnittstellenadresse, auf die Sie domänenübergreifend zugreifen möchten.
Serverseitige Unterstützung für CORS
wird hauptsächlich durch die Einstellung Access-Control-Allow-Origin
erreicht. Wenn der Browser die entsprechenden Einstellungen erkennt, kann er den domänenübergreifenden Ajax-Zugriff ermöglichen.
Um das domänenübergreifende Problem zu lösen, können wir die folgenden Methoden verwenden:
Jetzt das Problem? Was ist jsonp
? Die Wikipedia-Definition lautet: JSONP(JSON with Padding)
ist ein „Nutzungsmodus“ des Datenformats JSON
, der es Webseiten ermöglicht, Daten von anderen Domänen anzufordern.
JSONP
, auch gepolstertes JSON genannt, ist eine neue Methode zur Anwendung von JSON, bei der es sich lediglich um JSON handelt, das in Funktionsaufrufen enthalten ist, zum Beispiel:
callback({"name","trigkit4"});
JSONP besteht aus zwei Teilen : Rückruffunktion und Daten. Die Rückruffunktion ist die Funktion, die auf der Seite aufgerufen werden soll, wenn die Antwort eintrifft, und die Daten sind die JSON-Daten, die an die Rückruffunktion übergeben werden.
In js ist es nicht möglich, XMLHttpRequest
direkt zum Anfordern von Daten auf verschiedenen Domänen zu verwenden. Es ist jedoch möglich, js-Skriptdateien aus verschiedenen Domänen auf der Seite einzuführen, und jsonp nutzt diese Funktion, um dies zu erreichen. Beispiel:
<script type="text/javascript"> function dosomething(jsondata){ //处理获得的json数据 } </script> <script src="http://example.com/data.php?callback=dosomething"></script>
Nachdem die js-Datei erfolgreich geladen wurde, wird die Funktion ausgeführt, die wir im URL-Parameter angegeben haben, und die benötigten JSON-Daten werden als Parameter übergeben. Daher erfordert JSONP eine entsprechende Zusammenarbeit von der serverseitigen Seite.
<?php $callback = $_GET['callback'];//得到回调函数名 $data = array('a','b','c');//要返回的数据 echo $callback.'('.json_encode($data).')';//输出 ?>
Das Ausgabeergebnis lautet schließlich: dosomething(['a','b','c']);
Wenn Ihre Seite JQuery verwendet, können Sie JSONP-Vorgänge problemlos über die Kapselungsmethode ausführen.
<script type="text/javascript"> $.getJSON('http://example.com/data.php?callback=?,function(jsondata)'){ //处理获得的json数据 }); </script>
jquery
generiert automatisch eine globale Funktion, um das Fragezeichen in callback=?
zu ersetzen, und zerstört es dann automatisch, nachdem die Daten abgerufen wurden. Tatsächlich fungiert es als temporäre Proxy-Funktion. Die $.getJSON
-Methode ermittelt automatisch, ob es sich um eine domänenübergreifende Methode handelt. Wenn sie nicht domänenübergreifend ist, ruft sie die normale ajax
-Methode auf. Wenn es sich um eine domänenübergreifende Methode handelt, ruft sie die Rückruffunktion von jsonp
auf in Form des asynchronen Ladens einer js-Datei.
Die Vorteile von JSONP sind: Es ist nicht durch die gleiche Ursprungsrichtlinie eingeschränkt wie die vom XMLHttpRequest
-Objekt implementierte Ajax-Anfrage ist älter und kann in allen Browsern ausgeführt werden und erfordert keine XMLHttpRequest- oder ActiveX-Unterstützung. Nach Abschluss der Anforderung kann das Ergebnis durch einen Rückruf zurückgegeben werden.
Die Nachteile von JSONP sind: Es unterstützt nur GET-Anfragen, aber keine anderen Arten von HTTP-Anfragen wie POST; es unterstützt nur domänenübergreifende HTTP-Anfragen und kann das Problem der Interaktion zweier Seiten in unterschiedlichen Domänen nicht lösen einander. Probleme beim Tätigen von JavaScript
Anrufen.
CORS ist zweifellos fortschrittlicher, bequemer und zuverlässiger als JSONP.
1. JSONP kann nur GET-Anfragen implementieren, während CORS alle Arten von HTTP-Anfragen unterstützt.
2. Mit CORS können Entwickler gewöhnliches XMLHttpRequest verwenden, um Anfragen zu initiieren und Daten abzurufen, was eine bessere Fehlerbehandlung als JSONP bietet.
3. JSONP wird hauptsächlich von alten Browsern unterstützt, die CORS oft nicht unterstützen, während die meisten modernen Browser CORS bereits unterstützen.
Browser haben eine Same-Origin-Richtlinie, und eine ihrer Einschränkungen besteht darin, dass wir in der ersten Methode gesagt haben, dass sie keine Ajax-Methode an die Anforderung übergeben kann Dokumente aus verschiedenen Quellen. Die zweite Einschränkung besteht darin, dass js nicht zwischen Frames in verschiedenen Domänen im Browser interagieren kann.
Verschiedene Frameworks können das Fensterobjekt abrufen, jedoch nicht die entsprechenden Eigenschaften und Methoden. Beispielsweise gibt es eine Seite mit der Adresse http://www.php.cn/
, und der Quellcode dieser Seite lautet iframe
. Offensichtlich befinden sich diese Seite und der darin enthaltene Rahmen http://www.php.cn/
Wir können die Dinge in iframe
nicht bekommen, indem wir js-Code in die Seite schreiben: iframe
<script type="text/javascript"> function test(){ var iframe = document.getElementById('ifame'); var win = document.contentWindow;//可以获取到iframe里的window对象,但该window对象的属性和方法几乎是不可用的 var doc = win.document;//这里获取不到iframe里的document对象 var name = win.name;//这里同样获取不到window对象的name属性 } </script> <iframe id = "iframe" src="http://example.com/b.html" onload = "test()"></iframe>
这个时候,document.domain
就可以派上用场了,我们只要把http://www.php.cn/
和 http://www.php.cn/
这两个页面的document.domain都设成相同的域名就可以了。但要注意的是,document.domain的设置是有限制的,我们只能把document.domain设置成自身或更高一级的父域,且主域必须相同。
1.在页面 http://www.php.cn/
中设置document.domain
:
<iframe id = "iframe" src="http://example.com/b.html" onload = "test()"></iframe> <script type="text/javascript"> document.domain = 'example.com';//设置成主域 function test(){ alert(document.getElementById('iframe').contentWindow);//contentWindow 可取得子窗口的 window 对象 } </script>
2.在页面 http://www.php.cn/
中也设置document.domain
:
<script type="text/javascript"> document.domain = 'example.com';//在iframe载入这个页面也设置document.domain,使之与主页面的document.domain相同 </script>
修改document.domain
的方法只适用于不同子域的框架间的交互。
window
对象有个name
属性,该属性有个特征:即在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个window.name
的,每个页面对window.name
都有读写的权限,window.name
是持久存在一个窗口载入过的所有页面中的
window.postMessage(message,targetOrigin)
方法是html5
新引进的特性,可以使用它来向其它的window
对象发送消息,无论这个window对象是属于同源或不同源,目前IE8+、FireFox、Chrome、Opera
等浏览器都已经支持window.postMessage
方法。
以上就是JavaScript跨域问题代码总结的内容,更多相关内容请关注PHP中文网(www.php.cn)!