ajax使用,請求數(shù)據(jù),原理及封裝

先開始簡單的介紹下ajax這個東西。

ajax是什么:

ajax簡單的說就是做數(shù)據(jù)交互使用的。

Ajax的原理簡單來說通過XmlHttpRequest對象來向服務器發(fā)異步請求,從服務器獲得數(shù)據(jù),然后用javascript來操作DOM而更新頁面。這其中最關鍵的一步就是從服務器獲得請求數(shù)據(jù)。

Ajax的核心是JavaScript對象XmlHttpRequest。

ajax是異步的。

同步:一次一個,前一個沒完后一個不能開始
異步:一次一堆,前一個沒完后一個也能開始

ajax的優(yōu)點

Ajax的給我們帶來的好處大家基本上都深有體會,在這里我只簡單的講幾點:

** 1、** 最大的一點是頁面無刷新,在頁面內(nèi)與服務器通信,給用戶的體驗非常好。提高用戶體驗,節(jié)約資源,節(jié)約帶寬。

** 2、** 使用異步方式與服務器通信,不需要打斷用戶的操作,具有更加迅速的響應能力。

** 3、** 可以把以前一些服務器負擔的工作轉嫁到客戶端,利用客戶端閑置的能力來處理,減輕服務器和帶寬的負擔,節(jié)約空間和寬帶租用成本。并且減輕服務器的負擔,ajax的原則是“按需取數(shù)據(jù)”,可以最大程度的減少冗余請求,和響應對服務器造成的負擔。

** 4、** 基于標準化的并被廣泛支持的技術,不需要下載插件或者小程序。

缺點我就不說了。。。

下面開始正文介紹使用:

注:我們使用ajax不要想太多

** 1、** 后臺要什么——看接口文檔、問后臺、看代碼。
** 2、** 請求——要什么給什么
** 3、** 數(shù)據(jù)接收、解析
** 4、** 使用數(shù)據(jù)——跟ajax無關

首先說一下ajax的js原生封裝吧。

ajax封裝:

** 1、** 創(chuàng)建
** 2、** 拼字符串
** 3、** 連接服務器——
** 4、** 發(fā)送——
** 5、** 接收

封裝:

這里我就拿算是最終版的來說吧(根據(jù)一些框架的需要傳的參數(shù)來封裝)

當我們要用ajax時候 假設我有一個名字叫ajax的封裝函數(shù)

ajax({url:'',data:{},type:'',timeout:**,success:fn,error:fn);

解釋一下:參數(shù)比較多,所有就傳一個json。
url是你要路徑/文件等,下面我就假設有一個post.php文件,
data是我們要傳的數(shù)據(jù),服務器要什么,我們就傳什么,下面我就用a,b舉例。
type這個是有要交互的類型 類型常用有兩種:get,post,(至于jsonp在下面說,和這個不同)。
timeout時間,超過這個時間我就來中斷ajax,不能一直等著可不。

** 注** :****以下我會一直用這些參數(shù)來代替。

ajax({
    url:'post.php',
    data:{
        a:12,
        b:3
    },
    type:'post',
    timeout:5000,
    success:function(res){
        alert(res);
    },
    error:function(){
        alert('失敗了');
    }
})

那么現(xiàn)在我們就要開始寫這個封裝函數(shù)(假設接收行參名為json):

不解釋,先初始化我們傳的參數(shù)json;


json.data=json.data||{};    //很多時候可能不需要穿數(shù)據(jù)
json.type=json.type||'get'; //有時候我們并不會穿類型,就讓默認是通過get方式操作
json.timeout=json.timeout||0;   //這個是終止ajax的時間可能不會傳,默認就讓是0。
var timer=null;         //這個往了方便下面使用


** 第一步** :創(chuàng)建ajax對象,這里面因為ie不兼容的問題,所有要進行一次判斷在創(chuàng)建,不啰嗦,上代碼

//window.XMLHttpRequest條件是判斷有沒有這個東西;如果有就用這個創(chuàng)建,沒有就走else

if(window.XMLHttpRequest) { 
    var oAjax=new XMLHttpRequest(); //非iE
}else{
    var oAjax=new ActiveXObject('Microsoft.XMLHTTP'); //IE
}

當然出了這個方法還有簡單的,就是性能不好,但是我覺得沒什么區(qū)別。

try{
    var oAjax=new XMLHttpRequest();
}catch(e){  
    var oAjax=new ActiveXObject('Microsoft.XMLHTTP');
}

** 第二步** :拼接我們傳過來的數(shù)據(jù),我們要的是:post.php?a=12&b=3
這里面有必要說一下,有時候可能傳過來的數(shù)據(jù)是中文的 所有編碼一下
encodeURIComponent 編碼
decodeURIComponent 解碼

var arr=[]; //先建一個空數(shù)組,用來裝我們的數(shù)據(jù);
for(var name in json.data){ //data數(shù)據(jù)傳來的是一個json 
    arr.push(encodeURIComponent(name)+'='+encodeURIComponent(json.data[name])); //把數(shù)據(jù)用=號拼接
}
var sData=arr.join('&');    //最后把數(shù)據(jù)變成字符串用&拼接;

** 第三步** :鏈接服務器發(fā)送數(shù)據(jù)
因為post和get方式傳輸不同
POST和GET相比:
** 1.** 方法不同
** 2.** 數(shù)據(jù)發(fā)送地方不同——url+data、send(data)
** 3.** POST多一個頭
所有要判斷一下

if(json.type=='get'){
    oAjax.open('GET',json.url+'?'+sData,true);  //連接:方法,地址數(shù)據(jù),異步
    oAjax.send();       //發(fā)送
}else{
    oAjax.open('POST',json.url,true);   //連接:方式,地址,異步
    oAjax.setRequestHeader('content-type','application/x-www-form-urlencoded'); //發(fā)送頭
    oAjax.send(sData);  //發(fā)送
}

** 第四步** :接收服務器返回的東西
這里面需要說的是
on ready state change=>當通信狀態(tài)變化
ajax的readystate的狀態(tài)
readyState
0:初始化 ajax對象剛剛創(chuàng)建
1:已連接 ajax已經(jīng)連接到服務器
2:已發(fā)送
3:已接收-頭
4:已接收-內(nèi)容
只有到第四步的時候才操作

oAjax.onreadystatechange=function(){
    if(oAjax.readyState==4){    //當加載狀態(tài)到第四步的時候才算真正的成功
        clearTimeout(timer); //繼續(xù)往下看(清掉下面的一個定時器)
        //這個地方oAjax.status是狀態(tài)碼 http=>超文本傳輸協(xié)議
        //其中200-300之間是成功,304已經(jīng)請求過了 瀏覽器有緩存 這兩個算是成功
        if((oAjax.status>=200&&oAjax.status<300) || oAjax.status==304){
            //這一步是通過傳過來的success回調函數(shù)把成功的數(shù)據(jù)返回出去
                        json.success&&json.success(oAjax.responseText); 
            
                }else{
            //這一步代表失敗,我們把失敗的原因返回出去,以便方便分析和操作
                        json.error&&json.error(oAjax.status);
                }
         }
};
//這一步是比較特殊,就是如果請求超過我們傳輸進入的時間,就把ajax給中斷。不過首先判斷有沒有傳時間。

if(json.timeout){
                timer=setTimeout(function(){
                    oAjax.abort();
                },json.timeout)
            }

ok到這一步ajax的封裝已經(jīng)完成了。
ajax有一個最大的缺點,就是正常情況下不能跨域。
很多人說可以,那是因為很多庫里面把jsonp和ajax封裝到一塊了,所有感覺是ajax跨域,實際上不是。


下面開始說一下jsonp吧
jsonp:數(shù)據(jù)交互方式、可跨域
原理:本地定義一個函數(shù),根據(jù)script可以跨域的特性,通過script 在遠程服務器上帶著數(shù)據(jù)執(zhí)行這個函數(shù)
不多墨跡直接上代碼
也直接用ajax的傳參方式來封裝

jsonp({
   url:'http://suggestion.baidu.com/su',    //要訪問數(shù)據(jù)的地址接口
  data:{
     'wd':str,  //需要穿的數(shù)據(jù)
     'cb':'show'    //函數(shù)名
   },
   success:function(json){}
 })

下面開始寫封裝,不過多解釋跟上面ajax差不多看吧。

function jsonp(json){
var data=json.data;
var arr=[];
for(var name in data){
    arr.push(name+'='+data[name]);
}
var sData=arr.join('&');
var oS=document.createElement('script');
oS.src=json.url+'?'+sData;
document.head.appendChild(oS);
window.show=function(str){
    json.success(str) ;
    };
}


下面,簡單的說一下jq以及vue,anguar中ajax使用
框架中封裝的不用看,使用庫、框架等,不用管是怎么實現(xiàn)的,盡管用就行。這面ajax就是傳參的格式等不同。去看看api文檔就行。


首先說一下get方式

** 1、** jq中 :

$.ajax({
    url:**url,
    data:{
        a:15,
        b:13
    },
    type:'get',
    timeout:5000,
    success:function(res){
    },
    error:function(){}
    })

** 2、** angular中 :

$http.get(url,{
    params:{
        a:15,
        b:12
    }})
    .then(
        function(res){},
        function(){}
    )

** 3、** vue中 :

this.$http.get(
        url,
        {a:15,b:23}
          )
        .then(
            function(res){},
            function(){}
        )

總結:這里面基本是沒有區(qū)別,但是需要注意的是angular,和vue中 成功和失敗的兩個回調函數(shù)是寫在后面.then里面。
以及angular中傳輸數(shù)據(jù)是里面的params參數(shù)這個里面寫。仔細注意傳參方式就行,看看就懂了。


下面說一下post吧。

** 1、** jq中 :

$.ajax({
    url:'post.php',
    type:'post',
    timeout:5000,
    data:{
        a:16,
        b:14
    },
    success:function(res){
                    
                },
    error:function(){

                }
    })

** 2、** angular中:

//注意angular中post傳輸有問題,需要把傳輸?shù)念^以及拼接方法改一下
angular.config(['$httpProvider',function($httpProvider){
            $httpProvider.defaults.headers.post['Content-Type']='application/x-www-form-urlencoded';
            $httpProvider.defaults.transformRequest=function(data){
                var json=data.params;
                var arr=[];
                for(var name in json){
                    arr.push(name+'='+json[name]);
                }
                var sData=arr.join('&');
                return sData;
            };
        }]);
//開始交互
$http.post(url,{
                params:{
                    a:13,
                    b:12
                }
            })
        .then(
            function(res){},
            function(){}    
        )

** 3、** vue中 :

//注意 vue中post需要多傳輸一個 'emulateJSON':true
this.$http.post(url,
        {a:12,b:13},
        {'emulateJSON':true})
        .then(
            function(res){},
            function(){}    

                )

總結:jq中和之前傳輸沒是區(qū)別。
就是angular和vue中:angular需要把傳輸方式傳輸?shù)念^部改一下,以及拼接數(shù)據(jù)的方法修改才行。(angular太狂妄,想讓服務器配合它,但服務器不鳥它),vue中也需要改一下 不過就簡單多了就多傳一個參數(shù):'emulateJSON':true


下面說一下jsonp:

** 1、** jq中:

//需要多傳一個jsonp:'cb', dataType:'jsonp' 這個跟get,post有區(qū)別。
$.ajax(
    {url:url,
    jsonp:'cb',
    dataType:'jsonp',
    data:{
        wd:**
    },
    success:function(res){},
    error:function(){}
    }
     )

** 2、** angular中:

//注意這個里面 傳參還是一樣 但是需要多傳一個cb:'JSON_CALLBACK'
$http.jsonp(url,{
        params:{
            wd:***,
            cb:'JSON_CALLBACK'
                        }
           })
        .then(
            function(res){},
            function(){}
        )

** 3、** vue中 :

//這個要多傳一個jsonp:'cb'   不過這個cb根據(jù)不同的數(shù)據(jù)接口變化
this.$http.jsonp(url,
        {wd:***},
        {jsonp:'cb'})
        .then(
            function (res) {},
            function () {}
        )

總結一下:jq中注意:jsonp需要多傳一個jsonp:'cb', dataType:'jsonp' 這個跟get,post有區(qū)別。angular中注意:注意這個里面 傳參還是一樣 但是需要多傳一個cb:'JSON_CALLBACK'。vue中注意:這個要多傳一個jsonp:'cb' 不過cb根據(jù)不同的數(shù)據(jù)接口變化

以上結束。;

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,367評論 6 532
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,001評論 3 413
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,213評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,535評論 1 308
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,317評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,868評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,963評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,090評論 0 285
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,599評論 1 331
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,549評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,712評論 1 367
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,233評論 5 356
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 43,961評論 3 346
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,353評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,607評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,321評論 3 389
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,686評論 2 370

推薦閱讀更多精彩內(nèi)容