Ajax 瀏覽器跨域訪問控制

jsonp+ajax實現瀏覽器跨域通訊的原理解析javascript

php+ajax+P3P實現多域名跨域登陸php

一.關於跨域須要設置的響應頭消息

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瀏覽器差別性說明 

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

三.html5 postMessage 進行跨域

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

相關文章
相關標籤/搜索