前端校招準備--Ajax原理及其實現
前言
我們在請求資料的時候,往往會使用到ajax,而且一般都是通過引入jQuery庫,再使用。但是,如果我們想直接使用ajax怎麼辦呢,這個時候就可以自己寫一個ajax,剛一聽可能會覺得很難,但是看完我的文章後你肯定就會覺得原來這麼簡單~
正文
Ajax介紹
想象一個場景,你在淘寶上看中一件物品,想加入購物車,但是呢,你點選新增購物車後,整個頁面重新整理了,你之前看的物品記錄也沒有了,這樣是不是很煩(這是因為沒有使用ajax更新資料時,會請求整個頁面的資料,重新渲染)。
碰到這種情況,ajax就出場了,有了它,我們可以在點選新增商品後,只更新購物車中的物品數量就可以了,根本就不需要更新整個頁面,用官方一點的話來說,就是可以控制網頁的區域性重新整理。
ajax實現區域性重新整理的原理是通過XmlHttpRequest物件來向伺服器傳送非同步請求,通過js操作相應的DOM來更新頁面。
Ajax實現過程
ajax實現非同步請求的過程可以分為以下幾個步驟:
- 建立XmlHttpRequest物件
- 初始化引數
- 傳送資訊
- 接收資訊
從上面的介紹可以看出,ajax請求的核心在於XmlHttpRequest物件,所以瞭解了XmlHttpRequest的機制就相當於知道了ajax的執行過程。
在Chrome,Firefox,Opera,Safari以及IE7+都內建了XmlHttpRequest物件,但是IE5和IE6是使用ActiveX物件。
方法:
- abort(): 取消現在的連線,可以將XmlHttpRequest物件的狀態值重置為0
- open(): 初始化http的請求引數,但是不傳送請求
- send(): 傳送http請求
- setRequestHeader():給一個開啟但是未傳送的請求設定引數
屬性:
- onreadystateChange: 狀態改變觸發的回撥函式
- reposeText: 從伺服器返回資料的字串格式
- reposeXML: 從伺服器返回相容DOM的文件資料物件
- status: 從伺服器返回的狀態碼
- statusText: 伴隨狀態碼返回的資訊,如status=200時,statusText='OK'
-
readyState: 物件狀態值
0表示XmlHttpRequest物件已建立或者已經被abort()方法重置 1表示物件已經初始化,但是請求還未傳送(呼叫了open()方法,send()方法還沒有呼叫) 2表示請求已經發送,沒有接收到響應資訊(sed()方法已經被呼叫) 3表示已經接收到了所有的響應頭,響應體開始接收但未完成 4表示響應資訊已經全部接收
問題: http狀態碼(status)和物件的狀態值(readyState)有什麼區別?
回答:http狀態碼是指伺服器接收到請求後返回的一個狀態碼,其中比較常見的是200(請求成功),404(請求失敗),500(伺服器發生錯誤),更多參考這裡;而物件狀態值,是針對XmlHttpRequest物件的,前面已經解釋了每個狀態值代表的含義;它們倆之間的聯絡就是隻有當請求過程全部完成後,才可以根據伺服器返回的狀態碼呼叫不同的函式。
Ajax請求過程的程式碼實現
//封裝一個ajax請求
function ajax(options){
//建立XMLHttpRequest物件
if(window.XMLHttpRequest){
var xhr = new XMLHttpRequest
}else{
var xhr = new ActiveXObject()
}
//初始化引數的內容
options = options ||{}
options.type = (options.type ||'GET').toUpperCase()
options.dataType = options.dataType || 'json'
var params = options.data
//傳送請求
if(options.type == 'GET'){
xhr.open('GET',options.url + '?' + params,true)
xhr.send(null)
}else if(options.type == 'POST'){
xhr.open('POST',options.url,true)
xhr.send(params)
// xhr.setRequestHeader('Content-Type', "application/x-www-form-urlencoded")//規定輸出為鍵值對的形式
}
//接收請求
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
var status = xhr.status
if (status >= 200 && status < 300){
options.success && options.success(xhr.responseText,xhr.responseXML)
}else{
options.fail &&options.fail(status)
}
}
}
}
ajax({
type: 'post',
dataType: 'json',
data: {},
url: 'https://www.easy-mock.com/mock/5bbd92e0004caf3b6a68db6f/example/api/countEventsLevel',
success: function(text,xml){//請求成功後的回撥函式
console.log(text)
},
fail: function(status){////請求失敗後的回撥函式
console.log(status)
}
})
總結
其實與ajax請求相關的知識點很多,比如它的核心XmlHttpRequest物件,跨域問題等。由於本文中的重點在於手動實現ajax請求,所以這些內容暫時先不涉及,不過我會在文後將參考連結奉上,感興趣的可以看看。