按部就班Python3(十一) --6-- Ajax 實現跨域請求 jsonp 和 cors

 Ajax操做如何實現跨域請求?

 

        Ajax (XMLHttpRequest)請求受到同源策略的限制。
        Ajax經過XMLHttpRequest可以與遠程的服務器進行信息交互,另外XMLHttpRequest是一個純粹的Javascript對象,這樣的交互過程,是在後臺進行的,用戶不易察覺。
      所以,XMLHTTP實際上已經突破了原有的Javascript的安全限制。
   舉個例子:
         假設某網站引用了其它站點的javascript,這個站點被入侵併在javascript中加入獲取用戶輸入並經過ajax提交給其餘站點,這樣就能夠源源不斷收集信息。
           或者某網站由於存在漏洞致使XSS注入了javascript腳本,這個腳本就能夠經過ajax獲取用戶信息並經過ajax提交給其餘站點,這樣就能夠源源不斷收集信息。
            若是咱們又想利用XMLHTTP的無刷新異步交互能力,又不肯意公然突破Javascript的安全策略,能夠選擇的方案就是給XMLHTTP加上嚴格的同源限制。
             這樣的安全策略,很相似於Applet的安全策略。IFrame的限制還僅僅是不能訪問跨域HTMLDOM中的數據,而XMLHTTP則根本上限制了跨域請求的提交。(實際上下面提到了CORS已經放寬了限制)
             隨着Ajax技術和網絡服務的發展,對跨域的要求也愈來愈強烈。下面介紹Ajax的跨域技術。
 
 

(1)JSONP  (JSON with Padding

        JSONP(JSONP是JSON的一種「使用模式」),利用script標籤的src屬性(瀏覽器容許script標籤跨域) 。咱們知道<script>標籤能夠加載跨域的javascript腳本,而且被加載的腳本和當前文檔屬於同一個域。所以在文檔中能夠調用/訪問腳本中的數據和函數。若是javascript腳本中的數據是動態生成的,那麼只要在文檔中動態建立<script>標籤就能夠實現和服務端的數據交互。
       JSONP就是利用<script>標籤的跨域能力實現跨域數據的訪問,請求動態生成的JavaScript腳本同時帶一個callback函數名做爲參數。其中callback函數本地文檔的JavaScript函數,服務器端動態生成的腳本會產生數據,並在代碼中以產生的數據爲參數調用callback函數。當這段腳本加載到本地文檔時,callback函數就被調用。
       這裏須要明確的一點是:所謂的域跟js的存放服務器沒有關係,好比baidu.com的頁面加載了google.com的js,那麼此js的所在域是baidu.com而不是google.com。也就是說,此時該js能操做baidu.com的頁面對象,而不能操做google.com的頁面對象。
       若是還不太明白,這裏再詳細解釋一下: 由於經過script標籤引入的js是不受同源策略的限制的 (正如前文提到的baidu.com的頁面加載了google.com的js) 。因此咱們能夠經過script標籤引入一個js或者是一個其餘後綴形式(如 PHP ,jsp等)的文件,此文件返回一個js函數的調用,如返回JSONP_getUsers(["paco","john","lili"]),也就是說此文件返回的結果調用了JSONP_getUsers函數,而且把["paco","john","lili"]傳進去,這個["paco","john","lili"]是一個用戶列表。那麼若是此時咱們的頁面中有一個JSONP_getUsers函數,那麼JSONP_getUsers就被調用到,而且傳入了用戶列表。此時就實現了在本域獲取其餘域數據的功能,也就是跨域。
 
eg:
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8     <h1>Index</h1>
 9     <input type="button" onclick="JqAjax();" value="江西tv-list">
10     <div id="container"></div>
11     <script src="/static/jquery-2.1.4.min.js"></script>
12     <script>
13         function JqAjax() {
14             $.ajax({
15                 url:'http://www.jxntv.cn/data/jmd-jxtv2.html',
16                 type:'GET',
17                 dataType:'jsonp',
18                 jsonp: 'callback',
19                 jsonpCallback: 'list',
20                 success: function (param) {
21                     $.each(param.data,function (i) {
22                         var item = param.data[i];
23                         var str = "<p>"+ item.week +"</p>";
24                         var bq = $('#container');
25                         bq.append(str);
26                         $.each(item.list,function(j){
27                             var temp = "<span>"+item.list[j].time+"----</span><a href='" + item.list[j].link +"'>" + item.list[j].name +" </a><br/>";
28                             bq.append(temp);
29                         });
30                         bq.append("<hr/>");
31                     })
32                 }
33             })
34         }
35     </script>
36 </body>
37 </html>
展開

 

 

           爲何script標籤引入的文件不受同源策略的限制?由於script標籤引入的文件內容是不可以被客戶端的js獲取到的,不會影響到被引用文件的安全,因此不必使script標籤引入的文件遵循瀏覽器的同源策略。而經過ajax加載的文件內容是可以被客戶端js獲取到的,因此ajax必須遵循同源策略,不然被引入文件的內容會泄漏或者存在其餘風險。
 
JSONP的缺點是:它只支持GET請求而不支持POST等其它類型的HTTP請求。不過,通常get請求能完成全部功能。
 
           JSONP易於實現,可是也會存在一些安全隱患,若是第三方的腳本隨意地執行,那麼它就能夠篡改頁面內容,截獲敏感數據。可是在受信任的雙方傳遞數據,JSONP是很是合適的選擇。能夠看出來JSONP跨域通常用於獲取其餘域的數據。

通常可以用JSONP實現跨域就用JSONP實現,這也是前端用的最多的跨域方法。javascript

 
 
(2)CORS    (Cross origin resource sharing 即:跨域資源共享 )

    經過在HTTP Header中加入擴展字段,服務器在相應網頁頭部加入字段表示容許訪問的domain和HTTP method,客戶端檢查本身的域是否在容許列表中,決定是否處理響應。CORS協議提高了Ajax的跨域能力,但也增長了風險。一旦網站被注入腳本或XSS攻擊,將很是方便的獲取用戶信息並悄悄傳遞出去。
    假設咱們頁面或者應用已在 http://www.test1.com 上了,而咱們打算從 http://www.test2.com 請求提取數據。通常狀況下,若是咱們直接使用 AJAX 來請求將會失敗,瀏覽器也會返回「源不匹配」的錯誤。
      利用 CORS,在 http://www.test2.com 上只需添加一個標頭,就能夠容許來自 http://www.test1.com 的請求,下圖是我在PHP中的 hander() 設置,「*」號表示容許任何域向咱們的服務端提交請求:
        header('Access-Control-Allow-Origin:*');
也能夠設置指定的域名,如域名 http://www.test2.com ,那麼就容許來自這個域名的請求:
      header('Access-Control-Allow-Origin:http://www.test2.com'); php

 



相關文章
相關標籤/搜索