什么是Ajax
Ajax(Asynchronous JavaScript And XML),實(shí)際上就是異步的JavaScript和XML,Ajax是一種概念,指無(wú)需刷新頁(yè)面即可與服務(wù)器通信的技術(shù)。
記住:Ajax是一個(gè)技術(shù)統(tǒng)稱,包含了很多技術(shù),不是特指某一種技術(shù),也不是發(fā)送請(qǐng)求的一種方式。XMLHttpRequest 是實(shí)現(xiàn)Ajax的一種方式。
異步JavaScript
可以異步地向服務(wù)器端發(fā)送請(qǐng)求,在等待響應(yīng)的過程中,不會(huì)阻塞當(dāng)前頁(yè)面。瀏覽器還可以做自己的事情,直到成功獲取響應(yīng)后,瀏覽器才開始處理響應(yīng)數(shù)據(jù)。
XML
只是一種前后端傳輸數(shù)據(jù)的格式,現(xiàn)在主要用JSON。
應(yīng)用場(chǎng)景
Ajax通常用于創(chuàng)建快速響應(yīng)的Web程序,例如:
- 動(dòng)態(tài)更新內(nèi)容:比如在微博中,用戶發(fā)布新評(píng)論可以實(shí)時(shí)更新到頁(yè)面上,不需要刷新整個(gè)頁(yè)面。
- 自動(dòng)完成功能:利用百度搜索引擎時(shí),Ajax可以根據(jù)用戶輸入的內(nèi)容,及時(shí)向服務(wù)器發(fā)送請(qǐng)求并返回匹配的結(jié)果列表,提供反饋。
- 分頁(yè)和無(wú)限滾動(dòng):在展示博客文章等內(nèi)容時(shí),Ajax可以在用戶滾動(dòng)到底部時(shí)自動(dòng)加載更多內(nèi)容,或點(diǎn)擊分頁(yè)按鈕來(lái)加載特定數(shù)據(jù)塊,而不是一次性加載。
實(shí)現(xiàn)Ajax
我們來(lái)看一組代碼:
json
代碼解讀
復(fù)制代碼//test.josn的代碼
{
"reply":"我收到啦!"
}
ini
代碼解讀
復(fù)制代碼const xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if (xhr.readyState !== 4) return;
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
console.log(xhr.responseText);
}
};
xhr.open('GET', 'text.json', true);
xhr.send(null);
執(zhí)行結(jié)果如下:
這里有一點(diǎn)需要注意:JSON文件中的對(duì)象鍵名一定要用雙引號(hào)包裹,如果屬性值里有字符串,也需要用雙引號(hào)包裹。
執(zhí)行過程
1.創(chuàng)建xhr對(duì)象
ini
代碼解讀
復(fù)制代碼const xhr = new XMLHttpRequest();
2.利用onreadystatechange屬性,封裝一個(gè)函數(shù),來(lái)監(jiān)聽readyState的變化
ini
代碼解讀
復(fù)制代碼xhr.onreadystatechange = () => {
if (xhr.readyState !== 4) return;
if (xhr.status >= 200 && xhr.status < 300 ){
console.log(xhr.responseText);
}
};
2.1當(dāng)xhr對(duì)象執(zhí)行發(fā)送數(shù)據(jù)時(shí),有五種狀態(tài):
2.2判斷Http狀態(tài)碼
lua
代碼解讀
復(fù)制代碼if (xhr.status >= 200 && xhr.status < 300 ){
console.log(xhr.responseText);
}
Ajax的狀態(tài)碼為4是不夠的,這只能表示收到了服務(wù)器端所有的響應(yīng)的數(shù)據(jù),但不能保證這個(gè)數(shù)據(jù)是正確的。
所以還需要判斷Http的狀態(tài)碼,確保xhr對(duì)象的statue屬性值在200~300之間。
3.準(zhǔn)備發(fā)送請(qǐng)求
kotlin
代碼解讀
復(fù)制代碼xhr.open('GET','text.json',ture);
第一個(gè)參數(shù)是請(qǐng)求方式:method(“GET”或“POST”);第二個(gè)參數(shù)是:url(文件在服務(wù)器上的位置);第三個(gè)參數(shù)是:async(true:異步,false:同步)。
4.發(fā)送請(qǐng)求
csharp
代碼解讀
復(fù)制代碼xhr.send(null)
注意:send()的參數(shù)是通過請(qǐng)求體攜帶的數(shù)據(jù),而GET請(qǐng)求是通過請(qǐng)求頭攜帶數(shù)據(jù)的,所以要把send()參數(shù)設(shè)置為null。
Fetch
Fetch 出現(xiàn)在ES6,使用了ES6中的promise對(duì)象。是XMLHttpRequest的替代品。
大多數(shù)時(shí)候我們會(huì)將Ajax和Fetch放在一起比較,實(shí)際上比的是Ajax中的XMLHttpRequest和Fetch。
注意:Fetch是一個(gè)API,是基于Promise真實(shí)存在的。
Fetch的特點(diǎn)
- 基于Promise:Fetch會(huì)返回一個(gè)Promsie對(duì)象,使得異步操作更加簡(jiǎn)潔和理解。還可以通過鏈?zhǔn)秸{(diào)用
.then()
和.catch()
,可以更加清晰處理響應(yīng)和錯(cuò)誤。 - 簡(jiǎn)潔的API:Fetch有一套簡(jiǎn)潔的方法來(lái)執(zhí)行HTTP請(qǐng)求。
- 支持跨域請(qǐng)求:Fetch默認(rèn)支持跨域請(qǐng)求,但需要在服務(wù)器端配置CORS(跨域資源共享)。通過設(shè)置
credentials
屬性,還可以在跨域請(qǐng)求中發(fā)送cookies。 - 支持流式輸出:Fetch支持流式輸出,讓大型響應(yīng)或請(qǐng)求時(shí)更高效。
發(fā)送請(qǐng)求
Fetch 發(fā)送請(qǐng)求和Ajax相比較為簡(jiǎn)單,來(lái)看個(gè)POST請(qǐng)求:
javascript
代碼解讀
復(fù)制代碼fetch('https://example.com/api/data', {
method: 'POST', // 請(qǐng)求方法
headers: {
'Content-Type': 'application/json' // 指定發(fā)送的數(shù)據(jù)格式
},
body: JSON.stringify({ // 將 JavaScript 對(duì)象轉(zhuǎn)換為 JSON 字符串
name: 'Kimi',
age: 25
})
})
.then(response => response.json())
.then(data => console.log(data))
.catch(err => console.error('Fetch error:', err));
以上代碼就是向特定的端點(diǎn)發(fā)送包含用戶信息的POST請(qǐng)求,設(shè)定了請(qǐng)求頭和請(qǐng)求體來(lái)明確信息。
Axios
Axios是一個(gè)隨著Vue興起而被廣泛使用的,Vue大多數(shù)項(xiàng)目中都是利用Axios來(lái)發(fā)起請(qǐng)求的。
注意:Axios不是一個(gè)思想,也不是一個(gè)技術(shù)。而是一個(gè)基于Promise封裝的網(wǎng)絡(luò)請(qǐng)求庫(kù),是基于XMLHttpRequest進(jìn)行二次封裝。
那有沒有想過,為什么Axios是基于XMLHttpRequest的而不是Fetch?
原因有以下幾點(diǎn):
- 歷史性:在Axios首次開發(fā)時(shí),F(xiàn)etch還沒有被一個(gè)普遍使用,因?yàn)樗请S著ES6誕生的。而XMLHttpRequest已經(jīng)使用多年,幾乎所有瀏覽器都支持。
- 自動(dòng)轉(zhuǎn)換JSON數(shù)據(jù):Axios可以自動(dòng)將傳入傳出的數(shù)據(jù)轉(zhuǎn)換成JSON格式,但早期的Fetch需要手動(dòng)轉(zhuǎn)換。
- 請(qǐng)求和響應(yīng)攔截器:Axios允許在請(qǐng)求發(fā)送前或響應(yīng)被處理之前對(duì)其進(jìn)行修改或干預(yù),這有利于添加通用認(rèn)證令牌。Fetch本身不支持這種功能。
從Axios官網(wǎng)我們可以了解到Axios有以下特點(diǎn):
從瀏覽器創(chuàng)建 XMLHttpRequests
從 node.js 創(chuàng)建 http 請(qǐng)求
支持 Promise API
攔截請(qǐng)求和響應(yīng)
轉(zhuǎn)換請(qǐng)求和響應(yīng)數(shù)據(jù)
取消請(qǐng)求
超時(shí)處理
查詢參數(shù)序列化支持嵌套項(xiàng)處理
自動(dòng)將請(qǐng)求體序列化為:
- JSON (
application/json
) - Multipart / FormData (
multipart/form-data
) - URL encoded form (
application/x-www-form-urlencoded
)
- JSON (
將 HTML Form 轉(zhuǎn)換成 JSON 進(jìn)行請(qǐng)求
自動(dòng)轉(zhuǎn)換JSON數(shù)據(jù)
獲取瀏覽器和 node.js 的請(qǐng)求進(jìn)度,并提供額外的信息(速度、剩余時(shí)間)
為 node.js 設(shè)置帶寬限制
兼容符合規(guī)范的 FormData 和 Blob(包括 node.js)
客戶端支持防御XSRF 所以,Axios是XHR的一個(gè)子集,而XHR又是Ajax的一個(gè)子集。我們?cè)谝婚_始就說(shuō)過Axios是一個(gè)庫(kù),所以需要在使用時(shí)引入。
看個(gè)POST請(qǐng)求:
javascript
代碼解讀
復(fù)制代碼axios.post('/user', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
總結(jié)
網(wǎng)絡(luò)請(qǐng)求 | 特點(diǎn) |
---|---|
Ajax | 一種技術(shù)統(tǒng)稱,主要利用XHR實(shí)現(xiàn)網(wǎng)絡(luò)請(qǐng)求 |
Fetch | 具體API,基于promise,實(shí)現(xiàn)網(wǎng)絡(luò)請(qǐng)求 |
Axios | 一個(gè)封裝庫(kù),基于XHR封裝,推薦使用 |