新聞中心
前言
這篇文章主要聊一聊如何手寫一個jquery的ajax方法,這是前端中的基礎(chǔ)知識,也是一道非常經(jīng)典的前端面試題!

創(chuàng)新互聯(lián)主要從事網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計(jì)、網(wǎng)頁設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)海陵,10余年網(wǎng)站建設(shè)經(jīng)驗(yàn),價格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):13518219792
一步步手寫ajax
在web頁面中與后端通信的順序一般都是客戶端向服務(wù)器發(fā)起請求,然后服務(wù)器再回復(fù)客戶端,用于通信的工具就是ajax。如果你喜歡足球,你肯定知道荷甲聯(lián)賽中也有一支豪門足球俱樂部叫阿賈克斯,名字一毛一樣。ajax就像電話一樣,將頁面和服務(wù)器聯(lián)系在一起,基本用法如下:
圖1
從圖1中我們可以看出$.ajax是一個函數(shù),它的參數(shù)是一個對象,那么我們可以像如下這樣定義:
- var $ = {}; // 模擬jquery對象
- $.ajax = function(options){
- // 實(shí)現(xiàn)邏輯
- }
接下來我們就開始寫函數(shù)里面的邏輯。
圖2
如圖2,ajax的關(guān)鍵在于XMLHttpRequest對象,它提供了對http協(xié)議的安全訪問接口,這里使用了它的兩個方法和一個事件:
1)open方法的第一個參數(shù)是請求類型:get、post、head等,第二個參數(shù)是請求的接口地址,第三個參數(shù)表示ajax請求是異步(true)還是同步(false),如果是異步,在ajax發(fā)送完請求后js會繼續(xù)執(zhí)行,不會等待服務(wù)器響應(yīng),我們一般選擇異步,提高頁面的渲染效率;
2)send方法只有一個參數(shù),表示向服務(wù)器發(fā)送的參數(shù),一般是對象;
3)onreadystatechange是一個事件,它可以監(jiān)聽從請求開始到結(jié)束整個過程的狀態(tài),狀態(tài)保存在xhr的readyState屬性中。
readyState狀態(tài):
- 0代表未初始化,open方法還未執(zhí)行;
- 1代表正在加載,open已被執(zhí)行但send還未被執(zhí)行;
- 2代表已經(jīng)加載完畢,send已被執(zhí)行,請求已被發(fā)送;
- 3代表正在等待服務(wù)器響應(yīng);
- 4代表響應(yīng)已經(jīng)完成。
從上面readyState狀態(tài)我們可以看出,ajax只需要4的情況,其他狀態(tài)其實(shí)都是失敗!
另外,xhr的status屬性代表服務(wù)器返回的狀態(tài)碼,根據(jù)我們的經(jīng)驗(yàn),狀態(tài)碼在400以上都是有問題的,要么是服務(wù)端問題,要么就是客戶端問題!300到400之間好像都和重定向有關(guān)系,但是有一個除外——304,如果你了解瀏覽器緩存,你肯定知道它和協(xié)商緩存有關(guān)系,其實(shí)它代表請求成功!另外200以下的狀態(tài)都需要請求者繼續(xù)操作,也不符合要求!總結(jié)一下,可用的狀態(tài)碼就是200到300之間,加一個304!
好了,經(jīng)過上面的分析,我們繼續(xù)完善onreadystatechange事件的處理函數(shù):
圖3
如圖3,在事件處理函數(shù)中我們寫了兩個方法ajaxSuccess和ajaxError,它們分別執(zhí)行ajax參數(shù)對象傳入的success和error這兩個函數(shù)屬性。我們知道ajax對象參數(shù)中還一個屬性叫complete,這是一個方法,無論請求成功與否,它都會被執(zhí)行,所以它在ajaxSuccess和ajaxError中都需要被調(diào)用執(zhí)行一次。xhr.responseText代表服務(wù)器返回的數(shù)據(jù),xhr.statusText代表狀態(tài)碼對應(yīng)的狀態(tài)信息。
接下來我們還需要設(shè)置請求頭,可以用xhr.setRequestHeader來完成,如下:
圖4
圖4中,我們對兩個比較特殊的請求頭做了默認(rèn)設(shè)置(Accept和Content-type),其中當(dāng)我們用post類型向服務(wù)器發(fā)送請求并且?guī)в袇?shù),此時content-type需要設(shè)置為application/x-www-form-urlencoded,其他的請求頭可以通過ajax的對象參數(shù)headers屬性傳入。注意setRequestHeader方法需要在open方法之后調(diào)用!
在有些場景下,我們需要在發(fā)送請求前做一些邏輯判斷,如果不滿足條件我們需要阻止請求的發(fā)送,為了滿足需求,我們需要在ajax調(diào)用open方法之前添加一個鉤子!
圖5
圖5中我們通過beforeSend函數(shù)的執(zhí)行結(jié)果判斷是否需要取消請求!
寫到這里其實(shí)還有一步?jīng)]做,那就超時邏輯,比如在網(wǎng)絡(luò)不好的情況下,我們不能讓頁面一直處于loading狀態(tài),需要設(shè)置一個超時時間,超過這個時間就代表ajax請求失??!開發(fā)超時的需求,我們最容易想到的是利用定時器setTimeout,現(xiàn)在我們補(bǔ)上!
圖6
如圖6,在超時的情況下,我們將onreadystatechange事件處理函數(shù)置為一個空函數(shù)并且放棄這次請求,然后執(zhí)行error函數(shù),另外在正常的onreadystatechange事件處理邏輯中我們需要及時清除這個定時器!
寫到這里,一個簡單的ajax就已經(jīng)開發(fā)完了,現(xiàn)在直接把demo拿去使用也是沒有問題的!
常見面試題
1、手寫一個ajax?
如果你看到這里我想應(yīng)該沒什么問題了!
2、如果請求發(fā)生了重定向,ajax會怎么處理?
當(dāng)然是進(jìn)入了error函數(shù)中!
3、如果請求發(fā)生了超時,ajax會怎么處理?
當(dāng)然也是進(jìn)入了error函數(shù)中!
總結(jié)
本篇文章手寫的ajax可以直接用于移動端,未考慮PC端兼容性!根據(jù)我的經(jīng)驗(yàn),只要能手寫出ajax,面試中遇到相關(guān)問題就不會被難住,此類問題其實(shí)就是送分題!另外多說一點(diǎn),開發(fā)PC頁面時我們使用的是jquery,而開發(fā)移動端時我們應(yīng)該使用zepto.js!本篇文章就寫到這里,下一篇接著寫JSONP的實(shí)現(xiàn)!
文章名稱:手把手教你實(shí)現(xiàn)一個前端Jquery的Ajax,從此讓它成為面試的送分題
路徑分享:http://www.5511xx.com/article/codehpp.html


咨詢
建站咨詢
