同源政策
要了解跨域,先要說說同源政策。同源政策是由 Netscape 公司提出的一個著名的安全政策,所有支援 JavaScript 的浏覽器都會使用這個政策。所謂同源是指,域名,協定,端口相同。當頁面在執行一個腳本時會檢查通路的資源是否同源,如果非同源,那麼在請求資料時,浏覽器會在控制台中報一個異常,提示拒絕通路。
跨域
跨域,指的是從一個域名去請求另外一個域名的資源。即跨域名請求!跨域時,浏覽器不能執行其他域名網站的腳本,是由浏覽器的同源政策造成的,是浏覽器施加的安全限制。跨域的嚴格一點來說就是隻要協定,域名,端口有任何一個的不同,就被當作是跨域。
跨域解決方案
1、 通過jsonp跨域
2、 document.domain + iframe跨域
3、 location.hash + iframe
4、 window.name + iframe跨域
5、 postMessage跨域
6、 跨域資源共享(CORS)
7、 nginx代理跨域
8、 nodejs中間件代理跨域
9、 WebSocket協定跨域
JSONP的原理
ajax請求受同源政策影響,不允許進行跨域請求,但是web頁面上調用js檔案時則不受跨域的影響(不僅如此,我們還發現凡是擁有“src”這個屬性的标簽都擁有跨域的能力,比如<script>、<img>、<iframe>),利用這個特性,服務端不再傳回JSON格式的資料,而是傳回一段調用某個函數的js代碼,在src中進行了調用,這樣實作了跨域。細品下面代碼即可。
用戶端代碼:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script type="text/javascript">
// 得到航班資訊查詢結果後的回調函數
var flightHandler = function(data){
alert('你查詢的航班結果是:票價 ' + data.price + ' 元,' + '餘票 ' + data.tickets + ' 張。');
};
// 提供jsonp服務的url位址(不管是什麼類型的位址,最終生成的傳回值都是一段javascript代碼)
var url = "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=flightHandler";
// 建立script标簽,設定其屬性
var script = document.createElement('script');
script.setAttribute('src', url);
// 把script标簽加入head,此時調用開始
document.getElementsByTagName('head')[0].appendChild(script);
</script>
</head>
<body>
</body>
</html>
服務端傳回代碼:
flightHandler({
"code": "CA1998",
"price": 1780,
"tickets": 5
});
jquery對jsonp的實作
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Untitled Page</title>
<script type="text/javascript" src=jquery.min.js"></script>
<script type="text/javascript">
jQuery(document).ready(function(){
$.ajax({
type: "get",
async: false,
url: "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998",
dataType: "jsonp",
jsonp: "callback",//傳遞給請求處理程式或頁面的,用以獲得jsonp回調函數名的參數名(一般預設為:callback)
jsonpCallback:"flightHandler",//自定義的jsonp回調函數名稱,預設為jQuery自動生成的随機函數名,也可以寫"?",jQuery會自動為你處理資料
success: function(json){
alert('您查詢到航班資訊:票價: ' + json.price + ' 元,餘票: ' + json.tickets + ' 張。');
},
error: function(){
alert('fail');
}
});
});
</script>
</head>
<body>
</body>
</html>