天天看點

什麼是跨域?如何解決?

同源政策

  要了解跨域,先要說說同源政策。同源政策是由 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>