這些名詞的共同點(diǎn):都用于發(fā)送網(wǎng)絡(luò)請(qǐng)求。
1.Ajax
它的全稱是:Asynchronous JavaScript And XML,翻譯過(guò)來(lái)就是“異步的 Javascript 和 XML”。
很多小伙伴可能會(huì)誤以為 Ajax 是發(fā)請(qǐng)求的一種方式,或者把 XMLHttpRequest 與 Ajax 劃等號(hào),其實(shí)這是錯(cuò)誤和片面的。
正解:
Ajax 是一個(gè)技術(shù)統(tǒng)稱,是一個(gè)概念模型,它囊括了很多技術(shù),并不特指某一技術(shù),它很重要的特性之一就是讓頁(yè)面實(shí)現(xiàn)局部刷新。
特點(diǎn):
- 局部刷新頁(yè)面,無(wú)需重載整個(gè)頁(yè)面。
簡(jiǎn)單來(lái)說(shuō),Ajax 是一種思想,XMLHttpRequest 只是實(shí)現(xiàn) Ajax 的一種方式。其中 XMLHttpRequest 模塊就是實(shí)現(xiàn) Ajax 的一種很好的方式,這也是很多面試官喜歡讓面試者手撕的代碼之一。
利用 XMLHttpRequest 模塊實(shí)現(xiàn) Ajax。
示例代碼:
<body>
<script>
function ajax(url) {
const xhr = new XMLHttpRequest();
xhr.open("get", url, false);
xhr.onreadystatechange = function () {
// 異步回調(diào)函數(shù)
if (xhr.readyState === 4) {
if (xhr.status === 200) {
console.info("響應(yīng)結(jié)果", xhr.response)
}
}
}
xhr.send(null);
}
ajax('https://smallpig.site/api/category/getCategory')
</script>
</body>
復(fù)制代碼
輸出結(jié)果:

這里利用 XMLHttpRequest 模塊實(shí)現(xiàn)了一個(gè)最簡(jiǎn)單的 get 網(wǎng)絡(luò)請(qǐng)求。
注意: 我們使用這種方式實(shí)現(xiàn)網(wǎng)絡(luò)請(qǐng)求時(shí),如果請(qǐng)求內(nèi)部又包含請(qǐng)求,以此循環(huán),就會(huì)出現(xiàn)回調(diào)地獄,這也是一個(gè)詬病,后來(lái)才催生了更加優(yōu)雅的請(qǐng)求方式。
2.Fetch
Fetch 是在 ES6 出現(xiàn)的,它使用了 ES6 提出的 promise 對(duì)象。它是 XMLHttpRequest 的替代品。
很多小伙伴會(huì)把它與 Ajax 作比較,其實(shí)這是不對(duì)的,我們通常所說(shuō)的 Ajax 是指使用 XMLHttpRequest 實(shí)現(xiàn)的 Ajax,所以真正應(yīng)該和 XMLHttpRequest 作比較。
正解:
Fetch 是一個(gè) API,它是真實(shí)存在的,它是基于 promise 的。
特點(diǎn):
- 使用 promise,不使用回調(diào)函數(shù)。
- 采用模塊化設(shè)計(jì),比如 rep、res 等對(duì)象分散開(kāi)來(lái),比較友好。
- 通過(guò)數(shù)據(jù)流對(duì)象處理數(shù)據(jù),可以提高網(wǎng)站性能。
所以這里就和 Ajax 又很大不同了,一個(gè)是思想,一個(gè)是真實(shí)存在的 API,不過(guò)它們都是用來(lái)給網(wǎng)絡(luò)請(qǐng)求服務(wù)的,我們一起來(lái)看看利用 Fetch 實(shí)現(xiàn)網(wǎng)絡(luò)請(qǐng)求。
示例代碼:
<body>
<script>
function ajaxFetch(url) {
fetch(url).then(res => res.json()).then(data => {
console.info(data)
})
}
ajaxFetch('https://smallpig.site/api/category/getCategory')
</script>
</body>
復(fù)制代碼
輸出結(jié)果:

上段代碼利用 Fetch 發(fā)送了一個(gè)最簡(jiǎn)單的 get 請(qǐng)求,其中最重要的特點(diǎn)之一就是采用了.then 鏈?zhǔn)秸{(diào)用的方式處理結(jié)果,這樣不僅利于代碼的可讀,而且也解決了回調(diào)地獄的問(wèn)題。
3.Axios
Axios 是隨著 Vue 的興起而被廣泛使用的,目前來(lái)說(shuō),絕大多數(shù)的 Vue 項(xiàng)目中的網(wǎng)絡(luò)請(qǐng)求都是利用 Axios 發(fā)起的。當(dāng)然它并不是一個(gè)思想,或者一個(gè)原生 API,它是一個(gè)封裝庫(kù)。
正解:
Axios 是一個(gè)基于 promise 封裝的網(wǎng)絡(luò)請(qǐng)求庫(kù),它是基于 XHR 進(jìn)行二次封裝。
特點(diǎn):
- 從瀏覽器中創(chuàng)建 XMLHttpRequests
- 從 node.js 創(chuàng)建 http 請(qǐng)求
- 支持 Promise API
- 攔截請(qǐng)求和響應(yīng)
- 轉(zhuǎn)換請(qǐng)求數(shù)據(jù)和響應(yīng)數(shù)據(jù)
- 取消請(qǐng)求
- 自動(dòng)轉(zhuǎn)換 JSON 數(shù)據(jù)
- 客戶端支持防御 XSRF
所以說(shuō),Axios 可以說(shuō)是 XHR 的一個(gè)子集,而 XHR 又是 Ajax 的一個(gè)子集。既然說(shuō)它是一個(gè)庫(kù),那么我們?cè)谑褂玫臅r(shí)候就需要引入它。
示例代碼:
// 發(fā)送 POST 請(qǐng)求
axios({
method: 'post',
url: '/user/12345',
data: {
firstName: 'Fred',
lastName: 'Flintstone'
}
})
復(fù)制代碼
總結(jié)
Ajax、Fetch、axios三者之間的關(guān)系可以用一張圖來(lái)清晰的表示,如圖:

三者做個(gè)對(duì)比:
| 網(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封裝,較為推薦使用 |