從 AJAX 到 JSONP的基礎學習


 目錄索引:

一、AJAX的概念
二、POST && GET
三、原生實現AJAX簡單示例

  3.1 實現代碼
  3.2 重點說明
四、框架隱藏域

  4.1 基本概念
  4.2 后台寫入腳本
  4.3 JS主動判斷Iframe的改變
  4.4 表單提交數據實戰
五、JQ 的 AJAX
  5.1 load()
  5.2 $.get()
  5.3 $.post()
  5.4 $.getScript()
  5.5 $.getJson()
  5.6 $.ajax()
    a. 常用的屬性說明
    b. 常用的事件說明
    c. 全局事件說明
    d. $.ajaxSetup()
  5.7 AJAX的再次封裝
  5.8 序列化表單
六、JSONP的概念
  6.1 JSONP的概念
  6.2 自己封裝的JSONP
  6.3 JQ的JSONP使用。

 

一、AJAX的概念

AJAX(Asynchronous JavaScript And XML) 中文翻譯即“異步的JavaScript 和 XML”。
AJAX實際上是對現有的多種技術進行整合使用得到的技術。它包括:
  1) XMLHttpRequset:瀏覽器的XMLHttpRequset對象,該對象用於向后台發送請求與接收響應。
  2) JavaScript : 用於接收、處理、顯示XMLHttpRequest響應后的內容。
  3) XML : (Extensible Mrakup Language) 擴展的標記語言,它規定了一種統一的,可跨平台與系統的文本標記格式,而在AJAX中則用於前端與后台的數據格式定義,但實際上,現在已經很少會有人使用這種格式進行數據的傳輸,更多的是采用JSON數據格                   式,相比之下前者用於說明數據結構的冗余代碼更多,但是是結構清晰。
前面說過AJAX不是一種新的技術,而是對已有的技術進行整合得到的,其實AJAX的核心技術XMLHttpRequest是微軟率先在IE5.0瀏覽器上實現的,只是那時候一值將該功能作為一個ActiveXObject的插件使用,在IE實現該功能后,其它的瀏覽器,如google、firefox等則以自己的方式也實現了該功能,但是這個功能並沒有受到使用者的重視,一直到2005年谷歌在其旗下的Google Map和 Google Gmail等產品率先使用該技術,才讓AJAX技術真正的流行開來。
AJAX將的基本功能就是,當用戶在前端頁面發起請求后,這個請求會被XMLHttpRequest對象發送到后台,后台接收請求后進行處理,並將結果按照規定的數據格式,重新發送到前端,當前端頁面接響應收到的結果數據后,則會使用JS對數據進行解析、處理、展示等。


總之,AJAX技術的本質就是:實現頁面無刷新數據動態更改。
相比之前需要通過刷新頁面或者跳轉鏈接才能獲得響應的數據,AJAX具有以下幾點優勢:
  + 無刷新的數據獲取,提高用戶的體驗性。
  + 減輕服務器的帶寬
  + 后台與前端的緊密耦合
但是以上的優點,也會產生使用AJAX技術的缺點
  + 破壞瀏覽器的“前進”,“后退”按鈕
  + 對搜索引擎的SEO支持不好。

 

 二、POST && GET

POST 與 GET都是HTTP請求方式中的一種。而請求方式又決定了參數傳輸以及獲取數據方式的不同。
這里,我們只需要知道與了解POST 與 GET在應用層方面的差異即可。
  ·  GET請求會將參數跟在URL后進行傳遞,而POST請求則是作為HTTP消息的實體內容發送給WEB服務器。
  ·  GET方式傳輸數據有大小限制(通常不能大於2KB),而POST上傳輸數據,理論上不受限制。
  ·  GET方式傳輸的數據會被瀏覽器緩存,因此使用GET方式傳輸賬號,密碼之類的,就會有很大的風險。
  ·  GET方式和POST方式傳遞的數據在服務器端的獲取也不相同。在PHP中,GET方式的數據可以采用$_GET[]獲取,而POST則是$_POST[]獲取,但兩種都可以使用$_REQUEST[]獲取。

 

三、原生實現AJAX簡單示例

 3.1 實現代碼

  ·  前端代碼 ·

 1 function ajaxGetData(params){  2 
 3     var xhr = null, //創建接受XMLHttpRequest對象變量
 4         method = params.method && params.method.toUpperCase() || 'POST',  5         url = params.url || '',  6         data = params.data || null,  7         async = params.async || true, //異步還是同步,默認異步。
 8         callback = params.callback || function(){};  9 
10 
11     if(window.XMLHttpRequest){    //解決XMLHttpRequest對象的兼容性
12         xhr = new XMLHttpRequest(); 13     }else if(window.ActiveXObject){    //如果是IE6.0之前的,那么那么采用ActiveXObject對象。
14         xhr = new ActiveXObject('Microsoft.XMLHTTP'); 15     }else{ 16         return false;    //如果瀏覽器不支持該功能, 那么就阻止程序運行。
17  } 18 
19 
20     if(method === 'POST'){ 21         xhr.open('POST',url,async); 22         xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');//POST提交數據,專用頭部
23         xhr.send(data);    //發送請求,並附加數據,如果沒有數據,則為默認值,null
24  } 25 
26     if(method === 'GET'){ 27         (data)?'':data = ''; 28         xhr.open('GET',encodeURI(url+'?'+data),async);    //GET請求,通過URL附加數據傳輸。而通過編碼,可以解決IE6/7在GET方式下傳輸中文參數出現亂碼的情況。后台則可以通過 urldecode($_GET['a']) 進行解碼
29         xhr.send(null); 30  } 31 
32     xhr.onreadystatechange=function(){    //注冊請求的回調函數。
33         if(xhr.readyState == 4 && xhr.status == 200){    //readyState 這個是請求的狀態,4表示請求成功。 status表示響應應答或者數據傳輸的狀態。200表示數據傳輸成功。
34  callback(xhr); 35  } 36  } 37 
38 
39 }

  · 后端代碼 ·

1 <?php 2     $v1 = $_REQUEST['v1']; 3     $v2 = $_REQUEST['v2']; 4     echo ($v1+$v2); 5 ?>

  · 調用方式 ·

 1 elem.onclick=function(){  2  ajaxGetData({  3         url:'index.php',  4         method:'get',  5         data:'v1=1&v2=2',  6         async:true,  7         callback:function(xhr){  8  alert(xhr.responseText);  9  } 10  }); 11 };

 3.2 重點說明

· ActiveXObject
  ActiveX插件可以與微軟的其它組件進行交換,包括這里我需要的微軟自帶的HTTP請求方法。
  new ActiveXObjcet('Microsoft.XMLHTTP') IE5.0+ 支持的HTTP請求方法。

· setRequestHeader
  該方法可以設置請求的頭部信息,常用以post方式向一個動態網頁文件提交數據時使用。這是因為PHP中的$_POST['key']方法,需要用到鍵值對的格式,因此必須聲明請求的類型為: setRequestHeader('Content-Type','application/x-www-form-   urlencoded') 以表單提交數據的方式來發送數據到服務器。

· readyState && status
  readyState表示HTTP請求的運行狀態,不論請求的數據是否找到,都會經歷以下的過程:
    0 ---- 請求初始化,簡歷xhr對象。
    1 ---- 與服務器建立連接,open()方法已經成功調用。
    2 ---- 請求已經接收
    3 ---- 請求正在處理
    4 ---- 請求處理完成

   status 則表示了HTTP所請求數據的狀態[常見的反饋碼]:

    200 ---- 數據請求完成,已經可以使用。
    404 ---- 頁面未找到。

· open

   功能:初始化請求的參數。
   格式:open('請求數據的方式','所要請求的頁面URL','是否異步');
   說明:
      · 請求數據的方式:GET | POST
      · 是否異步:true(異步) | false(同步)
   * 如果存在setRequestHeader()方法,一定要把open()方法放在它之前的一行。

. send
   功能:發送請求。
   格式:send(params)
   代碼示例:
    send(null)
    //在GET方式下用這種方式,因為參數會在open方法中附加在URL后進行傳輸。

  send('fname=神&lname=經病')
    //在POST方式,用這種方式傳輸參數,但要記得使用setRequestHeader()方法。

. 同步與異步
   xmlHttpReq對象的open()方法第三個參數可以設置同步或異步的方式。
      true - 表示為異步,它不會等待服務器的執行完成。
     false - 表示同步,它會等待服務器執行完成,否則便會掛起程序,一直等待,一般不推薦是用同步的方式,不過對於一些小程序還是可以使用的。

· 使用時間戳或隨機數來確保無緩存的請求數據
  //時間戳
   open('GET','index.php?t='+ new Date()*1,true); 

  //隨機數
   open('GET','index.php?m='+ Math.random(),true); 

 

四、框架隱藏域

 4.1 基本概念

“框架隱藏域” 技術,現在主要用於文件上傳時使用,因為AJAX技術,無法實現文件的上傳。
  在AJAX技術提出之前,如果想實現無刷新的提交或改變數據,一般都是通過“框架隱藏域”來實現的。
“框架隱藏域”的基本思路就是:頁面會有一個空白的Iframe,通過display:none進行隱藏,然后在數據需要改變時,通過指定iframe的src值,讓其跳轉到所要請求的頁面。然后將值傳輸到后台,那么頁面的刷新,也會在隱藏的iframe中進行,當前窗口頁面並不會被刷新。最后父頁面在去獲取隱藏的iframe中的結果即可,這樣,便實現了通過隱藏iframe方式來實現無刷新的數據提交或改變。

一般來說,通過iframe實現無刷新,主要有以下幾種方法:

  將值作為url參數附加到iframe的src中。
  在iframe中放入一個表單,然后讓iframe中的表單進行提交
  將父頁面的表單元素的target值指定為iframe的name值。

而父頁面獲取隱藏iframe請求結果的方法,有以下幾種:

  + 通過onload,或JQ的load方法讀取改變后的iframe的值,切記一點是,onload事件一定要在iframe發生改變之前就要綁定。
  + 后台的結果是一段JavaScript代碼,改代碼會回調父頁面的指定方法,並傳輸請求結果:
     echo '<script>callback('數據提交成功')</script>' 

 

   4.2 后台寫入腳本

  · 前端代碼 ·

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5 </head>
 6 <body>
 7     <button>click</button>
 8     <iframe id="ifr" src="" style="display:none" frameborder="0"></iframe>
 9 </body>
10 </html>
11 <script>
12     var btn = document.getElementsByTagName('button')[0], 13  ifr = document.getElementById('ifr'); 14  btn.onclick=function(){ 15  ifr.src="index.php?v=success?"+new Date().getTime(); //加入時間戳
16  } 17 </script>

  · 后端代碼 ·

1 <?php 2     $v = $_REQUEST['v']; 3     echo '<script>alert("'.$v.'")</script>'; 4 ?>

  

   4.3 JS主動判斷Iframe的改變

  · 前端代碼 ·

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5 </head>
 6 <body>
 7     <button>click</button>
 8     <iframe id="ifr" src="" style="display:none" frameborder="0"></iframe>
 9 </body>
10 </html>
11     <script>
12         var btn = document.getElementsByTagName('button')[0], 13  ifr = document.getElementById('ifr'); 14         
15         function load(obj,fn){ 16 
17  obj.isloaded = false; 18  obj.onreadystatechange=function(){ 19                 if(this.readyState == 'complete'){ 20                     if(!this.isloaded){ 21                         this.isloaded = true; 22  fn && fn(); 23  } 24  } 25  }; 26  obj.onload=function(){ 27                if(!this.isloaded){ 28                    this.isloaded = true; 29  fn && fn(); 30  } 31  }; 32 
33  } 34 
35  btn.onclick=function(){ 36             
37  load(ifr,function(){alert(ifr.contentWindow.document.body.innerHTML)}); 38  ifr.src='index.php?'+new Date().getTime()+'&v=success'; 39         
40  }; 41 
42 </script>

  · 后端代碼 ·

1 <?php 2     $v = $_REQUEST['v']; 3     sleep(5); 4     echo 'success'; 5 ?>

 

   4.4 表單提交數據實戰

  · 前端代碼 ·

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5 </head>
 6 <body>
 7     <form action="index.php" method="post" target="MyIframe">
 8         <input type="text" name="v" />
 9         <input type="button" id="btn" value="SubMit" />
10     </form>
11     <iframe id="ifr" style="display:none" frameborder="0" name="MyIframe"></iframe>
12 </body>
13 </html>
14 <script>
15     var btn = document.getElementById('btn'), 16  ifr = document.getElementById('ifr'); 17     
18     function load(obj,fn){ 19 
20  obj.isOpen = false; 21  obj.onreadystatechange=function(){ 22             if(this.readyState == 'complete'){ 23                 if(!this.isOpen){ 24                     this.isOpen = true; 25  fn && fn(); 26  } 27  } 28  }; 29  obj.onload=function(){ 30            if(!this.isOpen){ 31                this.isOpen = true; 32  fn && fn(); 33  } 34  }; 35 
36  } 37 
38  btn.onclick=function(){ 39  document.forms[0].submit(); 40  load(ifr,function(){alert(ifr.contentWindow.document.body.innerHTML)}); 41         
42  }; 43     
44 
45 </script>

  附:關於 load() 方法的說明,見:http://www.cnblogs.com/HCJJ/p/5493821.html

 

五、JQ 的 AJAX

 5.1 load()

load方法是JQ中最簡單最常用的Ajax方法。它默認采用GET請求,使用異步的方式,常用於請求一些靜態的資源,例如HTML文件,然后插入到指定的DOM中。
load方法也可以指定請求的參數與回調函數,一旦指定了請求參數,那么load方法則會采用POST方式請求頁面。
一個完整的load方法使用格式:
  load(url,params,callback); 
  url : 是被請求頁面的url地址。若請求的頁面是一個html文件,那么可以在url后面空一個空格然后附加一個選擇器,便可以指定返回的內容,
  params : 請求時傳遞的參數,如果參數是一個對象,那么load便會使用POST方式請求,如果參數是一組鍵值對格式的字符串,那么則會采用GET請求。
  callback(data,status,xhr) : 請求完成時的回調函數。需要注意的是load方法的回調函數,不論請求成功還是失敗,只要請求完成就會觸發。
  data : 請求完成的值。
  status : 請求的狀態
  xhr : XMLHttpRequest對象。

示例:

1 $('div').load('news.html .para');    //附加選擇器
2 $('div').load('index.php','v=v1')    //附加參數,GET請求
3 $('div').load('index.php',{v:'v1'}) //附加參數,POST請求
4 $('div').load('index.php',{v:'v1'},function(data){$(this).html(data)})

 

   5.2 $.get()

$.get()方法使用GET方式來進行異步請求。
  $.get(url,params,callback) 
  params : 請求時傳輸的參數,可以是對象形式,也可以是一個序列化的字符串。
      對象格式:{v:'v1'}
      序列化的字符串:'v=v1&v2=v2';
  callback(data,status,xhr) : 注意的是,該函數只會在請求成功后才會被觸發。
示例:
     $.get('index.php',{v:'v1'},function(data){alert(data)}) 

 

   5.3 $.post()

$.post()方法使用POST方式進行異步請求。
 $.post(url,params,callback); 

 

   5.4 $.getScript()

$.getScript()方法會通過GET方式去請求一個腳本文件,並執行腳本代碼。
   $.getScript(url,callback); 
     url : 腳本文件的url
     callback(data,status):請求后的回調函數,data是腳本的內容,而status則是請求的狀態。

   5.5 $.getJson()

$.getJson()與$.getScript()方法相同,不過$.getJson()方法專門用於請求json文件。
   $.getJson(url,callback); 
     url : json文件的url
     callback(data):請求后的回調函數,data是響應的數據。

   5.6 $.ajax()

$.ajax()方法是JQ中最底層的AJAX方法,上面所說的都是基於$.ajax進行實現的。
學習$.ajax()方法,我們可以從兩個最基本點進行入手,就是屬性與事件。

a. 常用的屬性說明:

url:[str]:         指定請求頁面的url。
type:[str]:        設置請求的方式,是get還是post。
dataType[str]:     設置期望的后台返回數據格式。JQ會根據你指定的dataType類型進行數據的解析,因此如果不確定數據類型,這個地方可以不填,默認為JQ自動判斷。
data:[str | obj]:  指定傳輸到后台的數據參數。
async:[boolean]:   設置請求是同步方式還是異步方式,默認為異步。
global:[boolean]:  設置是否開啟AJAX的全局事件。
timeout:[number]:  設置超時時間。一旦后台響應的時間超過timeout的值,那么AJAX就會跳轉到error事件中,並且error事件中的xhr對象,會有一個statusText屬性返回值為timeout。
		    error:function(xhr){
			if(xhr.statusText == 'timeout'){
				alert('請求超時,請重新在試!');
			}
		     }
jsonp:[str] : 后台會根據該值或得回調函數名稱。


b. 常用的事件說明:

complete:當AJAX請求完成后觸發的事件。
success:當AJAX請求完成並且成功后觸發的事件。
error:當AJAX請求失敗后觸發的事件。
beforeSend:在AJAX准備發送之前觸發的事件。在該事件的處理程序中,可對當前AJAX的options做最后一次修改。
		beforeSend:function(event,xhr){
			xhr.type = 'get';
			xhr.url = 'xxx.php';
			event.success:function(){
					
			};
		}


c. 全局事件說明:

當頁面上存在任何ajax請求的時候都將觸發這些特定的全局ajax事件處理函數。
全局AJAX事件處理函數的注冊與執行,都是有一個特定的順序。

如圖:

其中:ajaxSend、ajaxSuccess、ajaxError、ajaxComplete都可以被頁面上所有的AJAX請求,而ajaxStart、ajaxStop則只會被觸發一次。

示例代碼:

 1 var start = 0,  2     send = 0;  3 $(document).ajaxStart(function(){  4     start++;  5 });  6 $(document).ajaxSend(function(){  7     send++;  8 });  9 $.ajaxSetup({'async':false}); 10 $.ajax({...}) //ajax1;
11 $.ajax({...}) //ajax2;
12 
13 console.log(start);  // --> 1;
14 console.log(send);     // --> 2;

因為ajaxSart()會在頁面上的第一個請求發起時觸發,ajaxStop()則會在最后一個請求結束時觸發,所以它們常常組合用於顯示loading等待框等。用來處理一群ajax請求。

另外需要注意是:

  • 全局事件永遠不會再跨域的腳本中運行,也不會再JSONP請求中運行。
  • 在jQuery1.8以上,所有的全局ajax事件處理函數必須綁定到document上,也就是$(document).ajaxEvent()
  • 只有在$.ajax()亦或$.ajaxSetup()中的globle設置成true才能使用ajax全局函數,false將不能使用。

  下面詳細說明每個AJAX的全局事件:   

    · ajaxStart()   

  ajax的全局事件。ajax請求開始發送時執行。
  該事件處理函數不會被連續觸發。
  格式:

1 $(document).ajaxStart(function(e){ 2     if(e.type === 'ajaxStart'){ 3         alert('ajax請求開始!'); 4  } 5 });

         *  e: 事件對象。

      · ajaxSend()

  ajax的全局事件。ajax請求發送時執行。
  該事件處理函數會被連續觸發。
  格式:  $(document).ajaxSend(function(e,xhr,opt){});

e:事件對象。
* xhr:XMLHttpRequest對象。
* opt:ajax參數選項。

    · ajaxSuccess()

ajax的全局事件。ajax請求成功時執行。
該事件處理函數會被連續觸發。
格式: $(document).ajaxSuccess(function(e,xhr,opt,res){}); 

* e:事件對象。
xhr:XMLHttpRequest對象。
opt:ajax參數選項。
res:ajax請求后 response返回的值。

· ajaxError()

ajax的全局事件。ajax請失敗時執行。
該事件處理函數會被連續觸發。
格式: $(document).ajaxError(function(e,xhr,opt,exc){}); 

* e:事件對象。
* xhr:XMLHttpRequest對象。
* opt:ajax參數選項。
* exc:失敗原因。常見值:Not Found

· ajaxComplete()

ajax的全局事件。ajax請失敗時執行。
該事件處理函數會被連續觸發。
格式: $(document).ajaxError(function(e,xhr,opt){}); 

* e:事件對象。
* xhr:XMLHttpRequest對象。
* opt:ajax參數選項。

· ajaxStop()

ajax的全局事件。ajax請求停止時執行。
格式:

1 $(document).ajaxStop(function(e){ 2     if(e.type === 'ajaxStop'){ 3         alert('ajax請求結束!'); 4  } 5 });

 

 

d. $.ajaxSetup()

在JQ的AJAX中,還有一個$.ajaxSetup方法,它可以全局的設置AJAX的默認參數選項。
示例:

 1 $.ajaxSetup({  2     url:'index.php',  3     type:'post',  4     dataType:'json',  5     error:function(){alert('error!!')}  6 });  7 
 8 oBtn.onclick=function(){  9  $.ajax({ 10         success:function(){ 11             alert('success'); 12  } 13  }); 14 }

 

   5.7 自己封裝的一個Ajax

  再AJAX基礎上再次封裝,目的是減少書寫AJAX代碼的冗余。

 1 function ajaxGetData(_url,_data,fn,_async){  2  $.ajax({  3         type:'post',  4  url:_url,  5         async:!_async,  6         dataType:'json',  7  data:_data,  8         success:function(data){  9             fn && fn(data); 10  }, 11         error:function(){ 12             alert('接口請求失敗,失敗地址:'+ _url); 13  } 14  }); 15 }

 

   5.8 序列化

在以往使用AJAX結合表單向后台傳輸參數時,我們需要用JS一個一個尋找表單控件元素,然后再一一取值附加到AJAX請求上。這對只有少量字段的表單勉強還可以使用。但如果表單元素越來越復雜,再使用這種方法就顯得缺乏彈性。
Jquery為了解決這一常用的操作,提供了以下幾個簡便的方法,它們分別可以序列化與JSON格式化form表單元素的值。
   serialize()  - 序列化表單元素的值。所謂的序列化,就是以k=v的鍵值對格式並通過&進行連接的字符串。
   serializeArray()  - 該方法並不會返回字符串的值。而是將表單元素的值序列化為一個Json格式的數據。
示例:

1 $(form).serialize(); //name1=v1&name2=v2
2 $(form).serializeArray(); //[{name:name1,v:v1},{name:name2,v:v2}]

而實現serialize方法的核心功能,則是JQ的$.param()。
 $.params() 方法,可以將一個普通的對象序列化成一個鍵值對格式的字符串返回。
示例: $.params({'key':'value'}); // 'key=value' 

 

六、JSONP

 6.1 JSONP的概念

JSONP(JavaScript Object Notaction With Padding) 就是采用JSON格式表示數據並由雙方開發人員相互約定的一種數據傳輸方法,該協議並不是一種公開標准的協議。只是一個相互約定的使用方法。
JSONP主要是利用HTML - script標簽可以跨域的特性來解決跨域數據的傳輸與交換。(實際上含有src屬性的HTML標記,都是可以跨域的)。
JSONP的核心思路就是通過script標簽去請求一個后台服務頁面的地址。然后在該后台頁面中,會調用前端HTML頁面中的一個事先定義好的函數,並將處理的結果作為函數的參數一並傳輸過去。
對於script標簽而言,它不論src指向的url是一個*.js的文件,還是其他格式的文件,例如.php或者.jsp等,只要這個url指向的文件能返回一個符合JavaScript語法與格式的字符串即可。

  JSONP的基本工作流程如圖所示:

  JSONP的基本工作流程代碼實現如下

  · 前端代碼 ·

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Document</title>
 6 </head>
 7 <body>
 8     
 9 </body>
10 </html>
11 <script src="http://hd.tzj.iwgame.com/js/jquery.min.js"></script>
12 <script>
13 
14     function callback(v){ 15  alert(v); 16  } 17 
18 
19 </script>
20 <script src="index.php"></script>

  · 后端代碼 ·

<?php $v = isset($_REQUEST['v'])? $_REQUEST['v'] : '"xxx"'; echo 'callback('.$v.')'; ?>

 

 6.2 自己封裝的JSONP

掌握JSONP的概念與基本的使用方式后,那么我們便可以封裝一個公用的JSONP方法,該方法可以將請求的需求參數,與回調函數名稱傳輸給后台,讓后台自動的去生成所要回調的函數與結果。減少前端與后台的每次溝通成本。
具體代碼如下:

 1 function JSONP(params){  2 
 3     var url = params.url,  4         data = params.data,  5         fn = params.callback,  6         oScript = document.createElement('script'),  7         hd = document.getElementsByTagName('head')[0],  8         callback = 'jsonp_'+ new Date().getTime()%1e6;  9 
10     window[callback] = function(data){ 11         
12  oScript.parentNode.removeChild(oScript); 13  fn(data); 14         window[callback] = undefined; 15         try{delete window[callback];}catch(e){;} 16 
17  }; 18 
19     oScript.src = url+'?data='+ data + '&callback=' + callback; 20  hd.appendChild(oScript); 21 
22 }

    使用方式如下:

1 JSONP({ 2     'url':'index.php', 3     'data':'condition=lt30', 4     'callback':function(data){alert(data)} 5 });

    后台代碼如下:

1 <?php 2     $fn = isset($_REQUEST['callback'])? $_REQUEST['callback'] : ''; 3     $data = isset($_REQUEST['data'])? $_REQUEST['data'] : ''; 4     if($fn){ 5         echo ''.$fn.'("'.$data.'")'; 6  } 7 ?>


 6.3 JQ的JSONP使用。

    接下來我們再看下,基於$.ajax()方法實現的JSONP請求。

1 $.ajax({
2     type:'get',
3     url:'index.php',
4     dataType:'jsonp',    //指定期望的返回結果是一個JSONP
5     jsonp:'callback',    //指定后台通過callback參數來接收到JQ自己創建的一個回調函數名稱。
6     data:'data=x',        
7     success:function(data){alert(data)}
8 });

   

    最后我們再總結一下,JSONP請求與傳統的AJAX請求的區別,幫我們更好的區分與認識這兩種機制。
      1. AJAX是基於XMLHttpRequest的並被同源策略所限制,而JSONP則是基於Script標簽,可跨域的數據交換協議。
      2. AJAX的核心是XMLHttpRequest,它是一個已經標准化的協議,而JSONP則是一種相互約定非公開的協議。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM