jsonp+ajax實現瀏覽器跨域通訊的原理解析javascript
Access-Control-Allow-Origin:* #容許全部主機 Access-Control-Allow-Origin:http://hello-world.example #容許特定主機 Access-Control-Allow-Methods: POST, GET, OPTIONS #容許跨域執行的方法 Access-Control-Allow-Headers: X-PINGOTHER,Content-Type,MyHeader #容許跨域設置的頭信息(若是不設置,那麼沒法獲取該值,甚至數據沒法獲取) Access-Control-Max-Age: 1728000
IE8和IE9使用新的API XDomainRequest(IE又淘氣了一次,但還好IE7上能夠經過ajax跨域)html
var xdr = new XDomainRequest(); xdr.onload = function (e) { //當收到服務器響應的回調函數 var data = $.parseJSON(xdr.responseText); if (data == null || typeof (data) == 'undefined') { data = $.parseJSON(data.firstChild.textContent); } //success }; xdr.onerror = function (e) { //error } xdr.open("GET", url); //目前只支持IE8和IE9 xdr.send();
對於webkit陣營的瀏覽器而言,須要使用ajax,這裏咱們不在多演示,咱們將在下面作一個兼容性的例子。html5
三.爲了達到兼容性的指標,咱們進行以下改造java
設立一站點 www.a.com,做爲請求的clientweb
<!doctype html> <html> <head> <meta charset="utf-8" /> <title>Cross-Domain</title> <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" /> </head> <body> <script type="text/javascript" charset="utf-8"> var xdr = null; if(!!window.XMLHttpRequest) { xdr = new XMLHttpRequest(); } else if( window.ActiveXObject) { try { //IE7+ xdr = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { //IE6- try { xdr = new ActiveXObject("Microsoft.XMLHTTP");} catch (e) { } } } if(xdr) { if(!("withCredentials" in xdr) && window.XDomainRequest) { xdr = new XDomainRequest(); }else{ xdr['withCredentials'] = true; } if(window.XMLHttpRequest && (xdr instanceof XMLHttpRequest))//若是是IE6,IE7,chrome,firefox,IE10,IE11 { xdr.open('OPTIONS', 'http://www.b.com/html5/crossdomain-server.php', true); } else if(window.ActiveXObject&&(xdr instanceof XDomainRequest))//若是是IE8,IE9 { xdr.open("POST", "http://www.b.com/html5/crossdomain-server.php"); } xdr.onload = function(e) { xdr.onReadyStateChange(arguments); }; xdr.onReadyStateChange = function(e) { if(window.console) { console.dir(xdr.responseText); }else{ alert(xdr.responseText); } } xdr.send(null); } else { alert('Not Supported !'); } </script> </body> </html>
設立服務器站點 www.b.com/html5/crossdomain-server.phpajax
<?php header('Content-Type:application/json;charset=utf-8'); header('Pragma:no-cache,no-store'); header('Cache-Control:no-cache,private'); header('Date:'+date('r')); header('Connection:Keep-Alive'); header('Access-Control-Allow-Origin: http://www.a.com'); header('Access-Control-Allow-Methods: POST, GET, OPTIONS,PUT,DELETE,HEAD'); header('Access-Control-Allow-Headers: X-PINGOTHER,Content-Type,Accept,Range'); header('Access-Control-Max-Age: 1728000'); header('Access-Control-Allow-Credentials: true'); date_default_timezone_set('Asia/Chongqing'); $data = array( 'id' => 'ZF1024', 'name'=>'zhangsan', 'token'=>uniqid() ); echo json_encode($data); ?>
請求結果chrome
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~apache
a.com/index.html中的代碼: <iframe id="ifr" src="b.com/index.html"></iframe> <script type="text/javascript"> window.onload = function() { var ifr = document.getElementById('ifr'); var targetOrigin = 'http://b.com'; // 若寫成'http://b.com/c/proxy.html'效果同樣 // 若寫成'http://c.com'就不會執行postMessage了 ifr.contentWindow.postMessage('I was there!', targetOrigin); //經過這句穿透域名限制 }; </script>
b.com/index.html中的代碼: <script type="text/javascript"> window.addEventListener('message', function(event){ // 經過origin屬性判斷消息來源地址 if (event.origin == 'http://a.com') { alert(event.data); // 彈出"I was there!" alert(event.source); // 對a.com、index.html中window對象的引用 // 但因爲同源策略,這裏event.source不能夠訪問window對象 } }, false);
最後,你還能夠經過apache服務器設置跨域json
<IfModule mod_setenvif.c> <IfModule mod_headers.c> <FilesMatch "\.(cur|gif|ico|jpe?g|png|svgz?|webp)$"> SetEnvIf Origin ":" IS_CORS Header set Access-Control-Allow-Origin "*" env=IS_CORS </FilesMatch> </IfModule> </IfModule>
參考:http://www.cnblogs.com/rainman/archive/2011/02/20/1959325.html#m2
http://msdn.microsoft.com/zh-cn/library/gg589525(v=vs.85).aspx