相見恨晚的AJAX(初識(shí)篇)

AJAX

要想要知道AJAX是什么呢,首先要知道一般情況下客戶端都會(huì)從服務(wù)器獲取了一些什么類型的文件;

  • 如果客戶端在服務(wù)器需要獲取的是資源文件,瀏覽器會(huì)自動(dòng)幫我們向服務(wù)器發(fā)送請(qǐng)求,并且接收服務(wù)器返回的內(nèi)容進(jìn)行渲染,最終顯示出來;(這里的資源文件包括JS,HTML,CSS,IMG等類型)
    向服務(wù)器發(fā)送請(qǐng)求資源文件基本可通過:
  • 在地址欄輸入網(wǎng)址
  • 利用LINK
  • 利用SCRIPT
  • 利用IFRAME
  • ...
  • 但是如果我們需要向服務(wù)器請(qǐng)求的是數(shù)據(jù)(這里的數(shù)據(jù)可能是json、text、xml等格式的),就需要使用AJAX等技術(shù)發(fā)送請(qǐng)求了(AJAX是JS中的一個(gè)核心重要知識(shí)點(diǎn))
    ‘AJAX 不是新的編程語言,而是一種使用現(xiàn)有標(biāo)準(zhǔn)的新方法。’ ---W3C的官方解釋

所以什么是AJAX:

AJAX: Async(Asynchronous) JavaScript And Xml
翻譯過來就是 :異步的JavaScript和Xml

  • 來自W3C的解釋:
    AJAX 是一種用于創(chuàng)建快速動(dòng)態(tài)網(wǎng)頁的技術(shù)。通過在后臺(tái)與服務(wù)器進(jìn)行少量數(shù)據(jù)交換,AJAX 可以使網(wǎng)頁實(shí)現(xiàn)異步更新。這意味著可以在不重新加載整個(gè)網(wǎng)頁的情況下,對(duì)網(wǎng)頁的某部分進(jìn)行更新。

  • 那么什么又是XML
  • AJAX叫做異步更新,難道使用異步請(qǐng)求嗎?
掃盲1 : 什么是XML
  • html :超文本標(biāo)記語言,W3C制定了很多具有語義化的標(biāo)記標(biāo)簽,我們使用這些HTML標(biāo)簽搭建頁面結(jié)構(gòu)(目前用的比較多的是 v4/v5(HTML5)版本)
  • xhtml:更加嚴(yán)格的HTML (用的比較少了)
  • dhtml:頁面中的數(shù)據(jù)是動(dòng)態(tài)綁定的 (非官方標(biāo)準(zhǔn)語言)
  • xml :可擴(kuò)展的標(biāo)記標(biāo)簽語言,它里面使用的標(biāo)簽都是自己定義的,也不是W3C的規(guī)范標(biāo)簽
  • 我們可以使用自己定義的有意義的標(biāo)簽來存儲(chǔ)數(shù)據(jù),這樣結(jié)構(gòu)清晰明了(目前前端數(shù)據(jù)存儲(chǔ)和展示一般都使用JSON,但是之前一般都是XML)

以前項(xiàng)目中服務(wù)器返回給客戶端的數(shù)據(jù)類型一般都是XML格式的,只不過XML格式的數(shù)據(jù)在客戶端的二次解析過程中相對(duì)于JSON比較麻煩,現(xiàn)在服務(wù)器端返回給客戶端的數(shù)據(jù)一般都是JSON格式的數(shù)據(jù);但是也有XML格式的數(shù)據(jù);

  • wxml:微信小程序的頁面就是.wxml ,小程序中使用的標(biāo)簽都是小程序自己定義的(微信XHML)
掃盲2 :異步JS -> 異步更新

在web1.0 web2.0時(shí)代初期, ==> 整體刷新
前端頁面中的功能和數(shù)據(jù)綁定大部分都是后臺(tái)開發(fā)者使用后臺(tái)語言來完成的;瀏覽器只有一個(gè)作用,就是把后臺(tái)實(shí)現(xiàn)好的功能的頁面呈現(xiàn)即可,所有的操作都是后臺(tái)在服務(wù)器完成的;這樣的話如果前端頁面中的內(nèi)容需要改變的話,必須后臺(tái)重新把最新的內(nèi)容返回,前端需要重新呈現(xiàn),導(dǎo)致整個(gè)前端頁面都刷新;

AJAX 里的Async(異步)先不要理解為JS中的同步異步編程(這樣會(huì)很混亂),這里面的異步可以先理解為‘局部刷新’,如果用七個(gè)字概述AJAX的作用,那就記住 “實(shí)現(xiàn)局部刷新的” 就Ok了;

舉一個(gè)非常簡(jiǎn)單的運(yùn)用AJAX的例子:
注冊(cè)百度賬號(hào)頁面中,


【運(yùn)用AJAX】注冊(cè)過程中,如果填寫一個(gè)已經(jīng)被注冊(cè)的手機(jī)號(hào),此時(shí),在點(diǎn)擊驗(yàn)證碼選框時(shí),該手機(jī)號(hào)的數(shù)據(jù)內(nèi)容便會(huì)傳送到服務(wù)器端進(jìn)行驗(yàn)證,會(huì)立馬彈出此手機(jī)已經(jīng)被綁定過的提示框;
【沒有運(yùn)用AJAX】整個(gè)數(shù)據(jù)傳輸過程中不會(huì)有任何提示框出現(xiàn),只有在全部表單填寫完成點(diǎn)擊注冊(cè)后完成一次數(shù)據(jù)傳輸,與服務(wù)器建立連接進(jìn)行確認(rèn),如果此時(shí)該手機(jī)被注冊(cè)的話,整個(gè)注冊(cè)頁面會(huì)被重新刷新后才會(huì)返回該手機(jī)被綁定的數(shù)據(jù)信息,并且之前表單中填寫信息都在刷新后清空,體驗(yàn)極差,所以一般此類頁面為了增加用戶體驗(yàn)都會(huì)運(yùn)用到AJAX;當(dāng)然還有很多運(yùn)用場(chǎng)景...

簡(jiǎn)單實(shí)現(xiàn)AJAX的基本步驟

1、 創(chuàng)建AJAX對(duì)象
var xhr = new XMLHttpRequest();  // ->IE6 下不兼容 不兼容用 new ActiveXObject
2 、打開一個(gè)請(qǐng)求的URL地址
xhr.open([method],[request url],[async/sync]);
  • [method] : 請(qǐng)求方式分為兩大系列:
  • get系列:
    • get : 獲取 (應(yīng)用于從服務(wù)器端獲取內(nèi)容)
    • delete :刪除,應(yīng)用于刪除服務(wù)器上的內(nèi)容
    • head :應(yīng)用于只想獲取服務(wù)器響應(yīng)頭信息
  • post系列:
    • post : 推送,應(yīng)用于給服務(wù)器推送內(nèi)容
    • put : 放,應(yīng)用于在服務(wù)器上放文件等
    • ...
  • 還有更多的請(qǐng)求方式

ps: 以上的幾種方式,客戶端都可以把內(nèi)容傳遞給服務(wù)器,服務(wù)器也可以把內(nèi)容返回給客戶端,只不過在不同的場(chǎng)景,我們使用對(duì)應(yīng)的類型會(huì)更好一些,以上沒有硬性規(guī)定,方式可以互換。只不過大家形成了一種約定俗成的默契,例如:
給服務(wù)器少,從服務(wù)器拿的多,我們最好用GET請(qǐng)求
給服務(wù)器多,從服務(wù)器拿的少,我們最好用POST請(qǐng)求

get請(qǐng)求和post請(qǐng)求的區(qū)別:

核心:

  • get請(qǐng)求傳遞給服務(wù)器的內(nèi)容是通過問號(hào)傳參的方式傳遞的;
    xhr.open('get','temp.json?xxx=xxx&xxx=xx')
  • post傳遞給服務(wù)器的內(nèi)容是用過請(qǐng)求主體傳遞的 ;
    xhr.send(...)

(1) GET傳遞給服務(wù)器的內(nèi)容沒有POST請(qǐng)求多 :
每一個(gè)瀏覽器對(duì)url的長度都有限制(谷歌8kb、火狐7kb、ie2kb),如果get請(qǐng)求下傳遞的比較多,url就會(huì)超出限制,超出的限制部分瀏覽器自動(dòng)截取,導(dǎo)致服務(wù)器獲取的內(nèi)容不完整;
而請(qǐng)求主體中的大小理論上是沒有限制的,但真實(shí)項(xiàng)目中為了保證傳輸?shù)乃俣龋覀儠?huì)限制傳遞內(nèi)容的大小.

(2) GET請(qǐng)求容易出現(xiàn)緩存 :
還是因?yàn)槭褂脝柼?hào)傳參的方式,如果重復(fù)向同一個(gè)地址發(fā)送請(qǐng)求,傳遞的參數(shù)值都是一樣的,瀏覽器會(huì)默認(rèn)的給做緩存(這個(gè)緩存不可控),所以我們一般項(xiàng)目中在使用get請(qǐng)求的時(shí)候都要把緩存清除掉;
xhr.open('get','temp.json?_='+Math.random());

(3) GET請(qǐng)求相對(duì)于POST來說不安全 :
有一種黑客技術(shù)叫做‘url劫持’,被劫持后,問號(hào)后面的參數(shù)值都會(huì)被獲取或者修改,導(dǎo)致不安全


  • [request url] :請(qǐng)求數(shù)據(jù)的接口地址,客戶端也是通過這個(gè)地址向服務(wù)器發(fā)送請(qǐng)求的,客戶端可以通過問號(hào)傳參的方式吧內(nèi)容傳遞給服務(wù)器;
  xhr.open('get','temp.json?name = zhangsan&age=18',true);
  • [async/sync] : 同步或者異步,默認(rèn)true 代表異步,可不寫;
    在真實(shí)項(xiàng)目中,為了防止出現(xiàn)請(qǐng)求堵塞的問題,我們大部分采用的是異步
    比如請(qǐng)求文件比較大,如果時(shí)間很長,響應(yīng)時(shí)間比較長就會(huì)影響后面的數(shù)據(jù)
3 、監(jiān)聽AJAX狀態(tài)改變,在不同的狀態(tài)下處理不同的事情
xhr.onreadystatechange = function(){
    if(xhr.readyState===4 && xhr.status ===200){
        var val = xhr.responseText;
        // -> xhr.getResponseHeader([key]) 獲取響應(yīng)頭信息
        // -> xhr.responseText: 獲取的是字符串(一般是服務(wù)器響應(yīng)主體
//返回的JSON字符串)
        // -> xhr.responseXML: 獲取的是XML數(shù)據(jù)
    }   
}
  • xhr.readyState :AJAX狀態(tài)碼



    0 UNSENT : 未發(fā)送,剛開始創(chuàng)建完成AJAX對(duì)象,默認(rèn)的狀態(tài)就是0
    1 OPENED : 已打開,執(zhí)行了xhr.open之后狀態(tài)變?yōu)?
    2 HEADERS_RECEIVED :響應(yīng)頭信息已經(jīng)成功的返回并且被接收
    3 LOADING : 響應(yīng)主體內(nèi)容正在加載
    4 DONE :響應(yīng)主體內(nèi)容接收成功


  • xhr.status : 服務(wù)器返回的HTTP網(wǎng)絡(luò)狀態(tài)碼
    200 : 請(qǐng)求成功
    【 3 開頭的都是成功但是有轉(zhuǎn)折】
    301 : 永久重定向(永久轉(zhuǎn)移) 例如:訪問京東以前的域名www.360buy.com
    在控制臺(tái)network里,可以看到301,域名更換的時(shí)候我們基本上都會(huì)做301做永久的重定向;
    302 : 臨時(shí)重定向(臨時(shí)轉(zhuǎn)移) --> 307(臨時(shí)重定向) ;例如:一臺(tái)服務(wù)器最高并發(fā)數(shù)在500左右,當(dāng)501個(gè)人過來的時(shí)候,當(dāng)前服務(wù)器不能有效的進(jìn)行處理了,此時(shí)我們需要把此客戶端的請(qǐng)求臨時(shí)轉(zhuǎn)移到另外一臺(tái)服務(wù)器上進(jìn)行處理;
    304 : 讀取的是緩存的數(shù)據(jù),在真實(shí)的項(xiàng)目中,產(chǎn)品一旦上線,資源圖片、JS、CSS等內(nèi)容是不輕易改變的,此時(shí)我們最好做一下304緩存:第一次向服務(wù)器發(fā)送請(qǐng)求來訪問的時(shí)候,把加載完成的資源文件進(jìn)行緩存,第二次直接讀取緩存中的數(shù)據(jù)即可,減少服務(wù)器壓力;
    【4開頭的一般都是客戶端的錯(cuò)誤】
    400 請(qǐng)求參數(shù)有誤
    401 請(qǐng)求的權(quán)限不夠
    404 請(qǐng)求的地址不存在
    【服務(wù)器端的錯(cuò)誤】
    500 未知的服務(wù)器端錯(cuò)誤 (停電,著火,服務(wù)器爆炸等等不可預(yù)知錯(cuò)誤....)
    503 服務(wù)器超負(fù)荷 (春運(yùn)搶票的時(shí)候你一定會(huì)看到這個(gè)狀態(tài))
4 、發(fā)送AJAX請(qǐng)求給服務(wù)器
xhr.send(null);
// -GET系列請(qǐng)求傳遞的一般都是null,因?yàn)樗麄兺ㄟ^問號(hào)傳參把內(nèi)容傳遞給服務(wù)器
// -POST系列的請(qǐng)求會(huì)把需要傳遞給服務(wù)器的內(nèi)容放在這里(請(qǐng)求主體);

AJAX整個(gè)過程中開始和結(jié)束標(biāo)志事件:
開始的標(biāo)志:xhr.send(...)
結(jié)束的標(biāo)志:xhr.readyState === 4


利用JQuery 實(shí)現(xiàn)AJAX

<script src="jquery.min.js"></script>
 $.ajax({
            url: 'temp.json',
            method: 'get',
//->type:'get' 和這個(gè)屬性是一樣的功能的,除了寫get還可以寫post、head、delete、put...
            dataType: 'json',
//->預(yù)設(shè)服務(wù)器返回的數(shù)據(jù)內(nèi)容的格式j(luò)son(默認(rèn))、text、xml...
            data: null,
//->設(shè)置請(qǐng)求主體的內(nèi)容,如果是GET請(qǐng)求,JQ會(huì)把這些內(nèi)容放到請(qǐng)求地址的末尾,通過問號(hào)傳參的方式傳遞給服務(wù)器,POST請(qǐng)求才是放在請(qǐng)求主體中
            cache: true,
//->是否保留GET請(qǐng)求的緩存,TRUE是保留也就是不清除GET緩存,設(shè)置成為FALSE是清除緩存(在URL末尾加隨機(jī)數(shù)),此參數(shù)對(duì)于POST請(qǐng)求無效
            async: true,
//->設(shè)置同步異步,默認(rèn)是TRUE代表異步
            //timeout:3000,//->設(shè)置請(qǐng)求超時(shí)的時(shí)間,如果超過3000MS,當(dāng)前請(qǐng)求自動(dòng)中斷(一般不用)
           success: function (result) {
               //->當(dāng)數(shù)據(jù)請(qǐng)求成功后執(zhí)行的回調(diào)函數(shù),result就是從服務(wù)器獲取的結(jié)果
                console.log(result);
           },
            error: function (msg) {
                //->當(dāng)數(shù)據(jù)請(qǐng)求失敗指定的回調(diào)函數(shù),msg就是失敗的原因
           }
       });

// JQ中的參數(shù)配置大概在20多個(gè)左右,以上只是最常用的幾個(gè)
/*
     * [data]
     * get->放在URL末尾
     * post->放在請(qǐng)求主體
     *
     * 字符串->寫的是什么傳遞就是什么
     * 對(duì)象->會(huì)把對(duì)象變成 key1=value1&key2=value2... 傳遞給服務(wù)器
     */

最后分享一道面試題:
問:有做過類似于倒計(jì)時(shí)的項(xiàng)目嗎,做的時(shí)候當(dāng)前時(shí)間是從客戶端本地讀取的還是從服務(wù)器讀取的?從服務(wù)讀取時(shí)間你是怎么解決時(shí)間差的?

<script>
    /*
     * 獲取服務(wù)器的時(shí)間,我們不需要再響應(yīng)主體中獲取,在響應(yīng)頭的信息中,
     * 有一個(gè)叫做Date的屬性,它存儲(chǔ)的值就是服務(wù)器的時(shí)間
     */
    var xhr = new XMLHttpRequest();
    xhr.open('head', 'temp.xml?_=' + Math.random());
//->為什么選擇HEAD請(qǐng)求方式?因?yàn)楫?dāng)前的需求,我們只想獲取到服務(wù)器時(shí)間,
//這樣的話只需要把響應(yīng)頭信息獲取到即可,主體內(nèi)容不需要獲取了,
//使用HEAD就是只獲取頭信息,加大請(qǐng)求的效率;
    xhr.onreadystatechange = function () {
        if (xhr.status !== 200) return;
        if (xhr.readyState === 2) {
//->我們只需要響應(yīng)頭信息返回就可以獲取到服務(wù)器的時(shí)間,如果等到4的時(shí)候,
//雖然也可以獲取到,但是間隔的時(shí)間更長了,導(dǎo)致時(shí)間差也會(huì)變大(真實(shí)時(shí)間和服務(wù)器獲取的時(shí)間差值)
            var time = xhr.getResponseHeader('Date');
//->獲取到的時(shí)間是格林尼治時(shí)間(GMT),我們還需要把這個(gè)時(shí)間變?yōu)楸本r(shí)間(GMT+0800)
            time = new Date(time);
            console.log(time);
        }
    };
    xhr.send(null);
</script>

以上就是對(duì)AJAX的一個(gè)初步的探索啦,這技術(shù)出道這么久,一直只聞其名不見其聲的技術(shù),還真有點(diǎn)相見恨晚的趕腳啊....
相信初學(xué)者看完此篇應(yīng)該會(huì)對(duì)AJAX有一個(gè)初步的理解了,目前也探索到這里,一起繼續(xù)探索吧,騷年們,如有異議,歡迎指正~!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,431評(píng)論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,637評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,555評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,900評(píng)論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,629評(píng)論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,976評(píng)論 1 328
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,976評(píng)論 3 448
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,139評(píng)論 0 290
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,686評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,411評(píng)論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,641評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,129評(píng)論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,820評(píng)論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,233評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,567評(píng)論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,362評(píng)論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,604評(píng)論 2 380

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