Ajax總結(jié)

一个从、Ajax簡介

1.Ajax相關(guān)

AJAX 全稱為Asynchronous Javascript And XML伶椿,就是異步的 JS 和 XML月褥。

通過AJAX可以在瀏覽器中向服務(wù)器發(fā)送異步請求等浊,最大的優(yōu)勢:無刷新獲取數(shù)據(jù)欲诺。

AJAX 不是新的編程語言抄谐,不是新的一門獨(dú)立的技術(shù),而是一種使用現(xiàn)有標(biāo)準(zhǔn)的新方法扰法。

2.XML相關(guān)

XML 可擴(kuò)展標(biāo)記語言蛹含。

XML 被設(shè)計(jì)用來傳輸和存儲數(shù)據(jù)。

XML和HTML類似塞颁,不同的是HTML中都是預(yù)定義標(biāo)簽浦箱,而XML中沒有預(yù)定義標(biāo)簽,全都是自定義標(biāo)簽祠锣,用來表示一些數(shù)據(jù)酷窥。

例如一個學(xué)生數(shù)據(jù):name = "孫悟空" ; age = 18 ; gender = "男" ;

用XML表示:

    <student>
        <name>孫悟空</name>
        <age>18</age>
        <gender>男</gender>
    </student>

用JSON表示:{"name":"孫悟空","age":18,"gender":"男"}

如今XML已經(jīng)被JSON取代了

3.Ajax的工作原理

Ajax的工作原理相當(dāng)于在用戶和服務(wù)器之間加了一個中間層(Ajax引擎),使用戶操作與服務(wù)器響應(yīng)異步化伴网。

4.Ajax的特點(diǎn)
  • 優(yōu)點(diǎn)
    可以無需刷新頁面而與服務(wù)器端進(jìn)行通信蓬推。
    允許你根據(jù)用戶事件來更新部分頁面內(nèi)容。
  • 缺點(diǎn)
    沒有瀏覽歷史澡腾,不能回退
    存在跨域問題
    SEO不友好

二沸伏、原生Ajax

1.原生Ajax發(fā)送get請求

步驟:

  • 實(shí)例化一個XMLHttpRequest對象
    XMLHttpRequest是核心對象,Ajax的所有操作都是通過該對象進(jìn)行的动分。

  • 給對象綁定一個事件監(jiān)聽

    在xhr內(nèi)部有五種狀態(tài)

    • 0:當(dāng)xhr被實(shí)例化出來毅糟,狀態(tài)就是0,即初始化狀態(tài)
    • 1:請求還沒有發(fā)出去澜公,即:send方法還沒有被調(diào)用姆另,依然可以修改請求頭
    • 2:請求已經(jīng)發(fā)出去了,即:send方法已經(jīng)被調(diào)用了玛瘸,不能再修改請求頭蜕青,響應(yīng)首行和響應(yīng)頭已經(jīng)回來了
    • 3:數(shù)據(jù)回來了,但是數(shù)據(jù)可能不完整糊渊,如果數(shù)據(jù)小右核,會在此階段直接接受完畢,數(shù)據(jù)大則有待于進(jìn)一步接受
    • 4:數(shù)據(jù)完全回來了
  • 指定發(fā)送請求的方式渺绒,地址贺喝,參數(shù)

  • 發(fā)送請求

    btn.onclick=function(){
        //1.實(shí)例化一個XMLHttpRequest對象
        const xhr=new XMLHttpRequest();
        //2.給對象綁定一個事件監(jiān)聽
        xhr.onreadystatechange=function(){
            if(xhr.readyState===4&&xhr.status===200){
                console.log(xhr.response);
                let demo=document.getElementById("demo");
                demo.innerHTML=xhr.response;
            }
        };
        //3.指定發(fā)送請求的方式菱鸥,地址,參數(shù)
        xhr.open("GET","http://localhost:3000/test_get?name=dexter&&age=20");
        //4.發(fā)送請求
        xhr.send();
    };

對于readyState狀態(tài)碼的說明
一般不會在0,1,2,3這幾種狀態(tài)的回調(diào)中躏鱼,做任何邏輯

    const xhr=new XMLHttpRequest();
    if(xhr.readyState===0){
        console.log("我出生了");
    }
    xhr.onreadystatechange = function () {
        if (xhr.readyState === 1) {
            xhr.setRequestHeader("demo", 123);
            console.log("請求還沒有發(fā)出去氮采,即:send方法還沒有被調(diào)用,依然可以修改請求頭");
        }
        if (xhr.readyState === 2) {
            //如果在這里修改請求頭會報(bào)錯
            console.log("請求已經(jīng)發(fā)出去了染苛,即:send方法已經(jīng)被調(diào)用了鹊漠,不能再修改請求頭,響應(yīng)首行和響應(yīng)頭已經(jīng)回來了");
            console.log(xhr.getResponseHeader("Date"));//Wed, 14 Oct 2020 12:28:58 GMT
        }
        if (xhr.readyState === 3) {
            console.log("數(shù)據(jù)回來了茶行,但是數(shù)據(jù)可能不完整躯概,如果數(shù)據(jù)小鹰椒,會在此階段直接接受完畢畏纲,數(shù)據(jù)大則有待于進(jìn)一步接受");
            console.log(xhr.response);//get請求發(fā)回的數(shù)據(jù)
        }
        if (xhr.readyState === 4) {
            console.log("數(shù)據(jù)完全回來了");
        }
    };
2.原生Ajax發(fā)送post請求

步驟

  • 實(shí)例化一個XMLHttpRequest對象
  • 給對象綁定一個事件監(jiān)聽
  • 指定發(fā)送請求的方式蒜埋,地址吗铐,參數(shù)
  • 設(shè)置post請求所特有的請求頭
  • 發(fā)送請求
    btn.onclick=function(){
        //1.實(shí)例化一個XMLHttpRequest對象
        const xhr=new XMLHttpRequest();
        //2.給對象綁定一個事件監(jiān)聽
        xhr.onreadystatechange=function(){
            if(xhr.readyState===4&&xhr.status===200){
                console.log(xhr.response);
                let demo=document.getElementById("demo");
                demo.innerHTML=xhr.response;
            }
        };
        //3.指定發(fā)送請求的方式戳吝,地址乌叶,參數(shù)
        xhr.open("POST","http://localhost:3000/test_post");
        //4.設(shè)置post請求所特有的請求頭
        xhr.setRequestHeader("content-type","application/x-www-form-urlencoded");
        //5.發(fā)送請求
        xhr.send("name=dexter&&age=20");
    };

post請求與get請求的區(qū)別是post請求需要設(shè)置特殊的請求頭否副,在發(fā)送數(shù)據(jù)時(shí)是在send中發(fā)送而get請求則是以urlencoded編碼形式發(fā)送壹粟。

3.IE中存在的問題

對于chrome和火狐來說伯铣,當(dāng)請求地址不發(fā)生變化時(shí)呻此,瀏覽器會嘗試走協(xié)商緩存。但是對于IE只要請求的地址不發(fā)生變化腔寡,會直接走強(qiáng)緩存趾诗,這樣會導(dǎo)致服務(wù)端修改了代碼但是瀏覽器刷新不出來效果的情況。因此在開發(fā)中為了應(yīng)對IE的強(qiáng)緩存蹬蚁,會在請求參數(shù)中加一個無關(guān)的時(shí)間戳參數(shù)恃泪。

    const xhr=new XMLHttpRequest();
    xhr.onreadystatechange=function(){
        if(xhr.readyState===4&&xhr.status===200){
            console.log(xhr.response);
            let demo=document.getElementById("demo");
            demo.innerHTML=xhr.response;
        }
    };
    xhr.open("GET","http://localhost:3000/test_get?name=dexter&age=20&t="+Date.now());
    xhr.send();
4.使用promise封裝原生Ajax
  • 定義發(fā)送Ajax發(fā)送請求的模板函數(shù)
    function sendAjax(url,method,data){
        return new Promise((resolve,reject)=>{
            //1.創(chuàng)建xhr對象
            let xhr=new XMLHttpRequest();
            //2.綁定監(jiān)聽
            xhr.onreadystatechange=function(){
                if(xhr.readyState!==4){
                    return
                }
                if(xhr.readyState===4&&(xhr.status>=200&&xhr.status<300)){
                    const responseObj={
                        data:xhr.response,
                        status:xhr.status,
                        statusText:xhr.statusText
                    };
                    resolve(responseObj);
                }else{
                    reject(new Error("請求出錯了"));
                }
            };
            //3.將傳遞過來的數(shù)據(jù)加工成urlencoded形式的編碼
            let dataKeys=Object.keys(data);//將對象的鍵封裝成數(shù)組的形式
            /* Array(3)
                0: "m"
                1: "n"
                2: "r"
                length: 3 */
            let str=dataKeys.reduce(function(pre,now){
                return pre+=`${now}=${data[now]}&`;
            },""); //m=1&n=2&r=4&
            //4.發(fā)送請求
            if(method.toLowerCase()==="get"){
                url+=`?${str}`;
                xhr.open(method,url);
                xhr.send();
            }else if(method.toLowerCase()==="post"){
                xhr.open(method,url);
                xhr.setRequestHeader("content-type","application/x-www-form-urlencoded");
                xhr.send(str);
            }
        })
    }
  • 發(fā)送get請求
    obj1={
        m:1,
        n:2,
        r:4
    };
    btn1.onclick=function(){
        sendAjax("http://localhost:3000/test_get","GET",obj1).then((data)=>{
            console.log(data);
        }).catch((err)=>{
            console.log(err);
        })
    };
  • 發(fā)送post請求
    obj2={
        name:"dexter",
        age:25
    }
    btn2.onclick=function(){
        sendAjax("http://localhost:3000/test_post","POST",obj2).then((data)=>{
            console.log(data);
        }).catch((err)=>{
            console.log(err);
        })
    };
5.服務(wù)端代碼
    const { request, response } = require("express");
    let express=require("express");
    let app=express();

    //暴露靜態(tài)資源
    app.use(express.static(__dirname+"/public"));
    //解析psot請求請求體中的urlencoded形式的參數(shù)
    app.use(express.urlencoded({extended:true}));

    app.get("/test_get",(request,response)=>{
        console.log("一個get請求來了",request.query);
        response.send("get請求發(fā)回的數(shù)據(jù)");
    })
    app.post("/test_post",(request,response)=>{
        console.log(request.body);
        console.log("一個post請求來了");
        response.send("post請求發(fā)回的數(shù)據(jù)");
    })

    app.listen(3000,(err)=>{
        if(!err){
            console.log("服務(wù)器已啟動,3000端口正在監(jiān)聽");
        }else{
            console.log(err);
        }
    })

三犀斋、取消上一次請求

問題描述:
當(dāng)用戶點(diǎn)擊鼠標(biāo)發(fā)送一次請求在沒有得到服務(wù)器響應(yīng)之前再次點(diǎn)擊了請求贝乎,或者連續(xù)多次發(fā)送請求,這樣會導(dǎo)致服務(wù)器在反映過來后向用戶多次返回相同的數(shù)據(jù)叽粹,造成用戶體驗(yàn)較差览效。因此應(yīng)當(dāng)對這樣的情況進(jìn)行處理,即當(dāng)用戶連續(xù)多次的發(fā)送同樣的請求時(shí)即使服務(wù)器當(dāng)下處理不過來虫几,在反應(yīng)過來時(shí)也只給用戶返回最后一次請求的數(shù)據(jù)锤灿。

    let lastxhr
    btn.onclick = function () {
        if (lastxhr) {
            lastxhr.abort();
            /* abort()的工作方式
            當(dāng)用戶點(diǎn)擊的速度一般時(shí),abort會追回用戶的請求辆脸,服務(wù)器不會接收到用戶的請求
            當(dāng)用戶點(diǎn)擊的速度非车#快時(shí)以至于abort追不上時(shí),abort會攔截服務(wù)器返回的數(shù)據(jù) */
        }
        lastxhr = getcode();
    };
    function getcode() {
        let xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4 && (xhr.status >= 200 && xhr.status < 300)) {
                console.log(xhr.response);
            }
        };
        xhr.open("GET", "http://localhost:3000/get_code");
        xhr.send();
        return xhr;
    }

服務(wù)端代碼

    app.get("/get_code",(request,response)=>{
        //返回一個1000-9999的數(shù)
        console.log("頁面請求驗(yàn)證碼");
        let code=Math.floor(Math.random()*8999+1000);
        setTimeout(()=>{
            response.send(code.toString());//如果返回一個純數(shù)字服務(wù)器會以為返回的是狀態(tài)碼而報(bào)錯
        },2000)
        
    })

四啡氢、使用jQuery封裝Ajax

1.jQuery發(fā)送get請求
  • 完整寫法中常用的幾個參數(shù)

    --method: 發(fā)送請求的方式
    --data: 要傳遞的數(shù)據(jù)
    --success: 成功的回調(diào)
    --error: 失敗的回調(diào)

    let btn1 = $("#btn1");
    btn1.click(function () {
        $.ajax("http://localhost:3000/test_get",{
            method:"GET",
            data:{
                name:"dexter",
                age:25
            },
            success:function(result){
                console.log(result);
            },
            error:function(err){
                console.log(err);
            }
        })
    })
  • 精簡寫法的參數(shù)

    精簡的寫法直接傳入請求地址和請求參數(shù)以及一個回調(diào)函數(shù)
    這個回調(diào)函數(shù)會有三個形參:
    第一個形參表示返回來的數(shù)據(jù)
    第二個參數(shù)表示當(dāng)前請求的狀態(tài)
    第三個參數(shù)是內(nèi)部使用的xhr對象
    但是一般在使用時(shí)只傳進(jìn)去一個參數(shù)状囱,即服務(wù)器返回來的數(shù)據(jù)

    $.get("http://localhost:3000/test_get", { name: "dexter", age: 25 }, (data) => {
        console.log(data);
    })
2.jQuery發(fā)送post請求
  • 完整寫法
    btn2.click(function () {
        $.ajax("http://localhost:3000/test_post",{
            method:"POST",
            data:{
                name:"dexter",
                age:25
            },
            success:function(result){
                console.log(result);
            },
            error:function(err){
                console.log(err);
            }
        })
    })
  • 精簡寫法
    $.post("http://localhost:3000/test_post", { name: "dexter", age: 25 }, (data) => {
        console.log(data);
    })
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末术裸,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子亭枷,更是在濱河造成了極大的恐慌袭艺,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件叨粘,死亡現(xiàn)場離奇詭異猾编,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)升敲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門袍镀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人冻晤,你說我怎么就攤上這事〕裎” “怎么了鼻弧?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長锦茁。 經(jīng)常有香客問我攘轩,道長,這世上最難降的妖魔是什么码俩? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任度帮,我火速辦了婚禮,結(jié)果婚禮上稿存,老公的妹妹穿的比我還像新娘笨篷。我一直安慰自己,他們只是感情好瓣履,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布率翅。 她就那樣靜靜地躺著,像睡著了一般袖迎。 火紅的嫁衣襯著肌膚如雪冕臭。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天燕锥,我揣著相機(jī)與錄音辜贵,去河邊找鬼。 笑死归形,一個胖子當(dāng)著我的面吹牛托慨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播暇榴,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼榴芳,長吁一口氣:“原來是場噩夢啊……” “哼嗡靡!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起窟感,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤讨彼,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后柿祈,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體哈误,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年躏嚎,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蜜自。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡卢佣,死狀恐怖重荠,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情虚茶,我是刑警寧澤戈鲁,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站嘹叫,受9級特大地震影響婆殿,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜罩扇,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一婆芦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧喂饥,春花似錦消约、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至集侯,卻和暖如春被啼,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背棠枉。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工浓体, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人辈讶。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓命浴,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子生闲,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評論 2 345

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

  • 原文出處 http://blog.poetries.top/2016/11/26/Ajax-summary 關(guān)注公...
    程序員poetry閱讀 6,681評論 3 110
  • 本文主要總結(jié)整理Ajax的一些常用的基礎(chǔ)知識媳溺,適合初學(xué)者。 一碍讯、Ajax簡介悬蔽、優(yōu)劣勢、應(yīng)用場景以及技術(shù) Ajax簡...
    Aniugel閱讀 591評論 0 1
  • AJAX = Asynchronous JavaScript and XML(異步的 JavaScript 和 X...
    fenerchen閱讀 545評論 0 2
  • 18.3.23·AJAX概念簡述捉兴、內(nèi)部實(shí)現(xiàn)原理 ·常用方法:load()蝎困、$.get()、$.post()倍啥、$.g...
    靜心安分讀書閱讀 242評論 0 3
  • Ajax 什么是Ajax Ajax = 異步 JavaScript 和 XML禾乘。 AJAX 是一種用于創(chuàng)建快速動態(tài)...
    有你不苦_閱讀 391評論 0 2