從 AJAX 到 JSONP的基礎學習

目錄索引:php

1、AJAX的概念
2、POST && GET
3、原生實現AJAX簡單示例html

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

  4.1 基本概念
  4.2 後臺寫入腳本
  4.3 JS主動判斷Iframe的改變
  4.4 表單提交數據實戰
5、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 序列化表單
6、JSONP的概念
  6.1 JSONP的概念
  6.2 本身封裝的JSONP
  6.3 JQ的JSONP使用。jquery

 

1、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具備如下幾點優點:
  + 無刷新的數據獲取,提升用戶的體驗性。
  + 減輕服務器的帶寬
  + 後臺與前端的緊密耦合
可是以上的優勢,也會產生使用AJAX技術的缺點
  + 破壞瀏覽器的「前進」,「後退」按鈕
  + 對搜索引擎的SEO支持很差。json

 

 2、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[]獲取。小程序

 

3、原生實現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、框架隱藏域

 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

 

5、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' 

 

6、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則是一種相互約定非公開的協議。

相關文章
相關標籤/搜索