【JS】1857- 你知道 XHR 和 Fetch 的區(qū)別嗎?

現(xiàn)如今,網(wǎng)站開發(fā)普遍采用前后端分離的模式,數(shù)據(jù)交互成為了不可或缺的關(guān)鍵環(huán)節(jié)。在這個(gè)過程中,XHR 和 Fetch API 是兩種最常見的方法,用于從 Web 服務(wù)器獲取數(shù)據(jù)。XHR 是一種傳統(tǒng)的數(shù)據(jù)請(qǐng)求方式,而 Fetch API 則代表了現(xiàn)代 Web 開發(fā)的新興標(biāo)準(zhǔn)。接下來,我們將一同深入學(xué)習(xí)它們的使用方法和適用場景。
XMLHttpRequest
XMLHttpRequest[1],通常簡稱為 XHR。通過 XMLHttpRequest 可以在不刷新頁面的情況下請(qǐng)求特定 URL,獲取數(shù)據(jù)。XMLHttpRequest 在 AJAX 編程中(比如 jquery)被大量使用。
AJAX[2] :異步 JavaScript 和 XML。許多人容易把它和 jq 的 ajax 混淆。它是一個(gè)技術(shù)統(tǒng)稱,本身不是一種技術(shù)。
特點(diǎn)
-
異步請(qǐng)求:XHR 允許進(jìn)行異步請(qǐng)求,它可以在后臺(tái)執(zhí)行,而不會(huì)阻止頁面的其他操作。 -
支持跨域請(qǐng)求:通過服務(wù)器端設(shè)置允許跨域請(qǐng)求,從不同域的服務(wù)器獲取數(shù)據(jù)。 -
事件驅(qū)動(dòng):提供了 onload、onerror、onprogress等一系列事件來監(jiān)聽請(qǐng)求的狀態(tài)變化。 -
靈活性:提供了對(duì)請(qǐng)求頭、響應(yīng)頭以及請(qǐng)求方法的完全控制,使其非常靈活。
工作原理
XHR 的工作原理主要為:
-
創(chuàng)建 XHR 對(duì)象實(shí)例:通過 new XMLHttpRequest()創(chuàng)建一個(gè) XHR 對(duì)象。 -
配置請(qǐng)求:使用 open()方法設(shè)置請(qǐng)求方法(GET、POST 等)、URL,以及是否要異步執(zhí)行請(qǐng)求。 -
設(shè)置回調(diào)函數(shù):設(shè)置事件處理程序來處理請(qǐng)求完成、成功、失敗等不同的狀態(tài)。 -
發(fā)起請(qǐng)求:使用 send()方法發(fā)送請(qǐng)求。 -
處理響應(yīng):在事件處理程序中處理響應(yīng)數(shù)據(jù),通常使用 responseText或responseXML來訪問響應(yīng)內(nèi)容。
// 創(chuàng)建一個(gè)新的XHR對(duì)象
const xhr = new XMLHttpRequest();
// 配置請(qǐng)求
xhr.open("GET", "https://api.baidu.com/test", true);
// 設(shè)置響應(yīng)處理函數(shù)
xhr.onload = function() {
if (xhr.status === 200) {
// 請(qǐng)求成功
const responseData = xhr.responseText;
console.log("成功獲取數(shù)據(jù):", responseData);
} else {
// 請(qǐng)求失敗
console.error("請(qǐng)求失敗,狀態(tài)碼:" + xhr.status);
}
};
// 發(fā)起請(qǐng)求
xhr.send();
XHR 的響應(yīng)處理通常在onreadystatechange事件處理程序中完成。在上面的例子中,我們等待 XHR 對(duì)象的狀態(tài)變?yōu)?nbsp;4(表示請(qǐng)求完成)并且 HTTP 狀態(tài)碼為 200(表示成功響應(yīng))時(shí),解析響應(yīng)數(shù)據(jù)。
Fetch API
Fetch[3] 是一種現(xiàn)代的數(shù)據(jù)網(wǎng)絡(luò)請(qǐng)求 API,它旨在解決 XHR 的一些問題,提供了更強(qiáng)大、更靈活的方式來處理 HTTP 請(qǐng)求。可以理解為 XMLHttpRequest 的升級(jí)版。
特點(diǎn)
-
Promise 風(fēng)格:Fetch API 使用 Promise對(duì)象來處理異步請(qǐng)求,使代碼更具可讀性和可維護(hù)性。 -
更簡單的語法:相較于 XHR,F(xiàn)etch API 的語法更加簡單明了,通常只需要幾行代碼來完成請(qǐng)求。 -
默認(rèn)不接受跨域請(qǐng)求:為了安全性,F(xiàn)etch API 默認(rèn)不接受跨域請(qǐng)求,但可以通過 CORS(跨域資源共享)來進(jìn)行配置。 -
更現(xiàn)代的架構(gòu):Fetch API 是建立在 Promise和Stream之上的,支持更靈活的數(shù)據(jù)處理和流式傳輸。
工作原理
Fetch 的工作原理主要為:
-
使用 fetch()函數(shù)創(chuàng)建請(qǐng)求:傳入要請(qǐng)求的 URL,以及可選的配置參數(shù),例如請(qǐng)求方法、請(qǐng)求頭等。 -
處理響應(yīng): fetch()返回一個(gè) Promise,您可以使用.then()鏈?zhǔn)秸{(diào)用來處理響應(yīng)數(shù)據(jù),例如使用.json()方法解析 JSON 數(shù)據(jù)或.text()方法獲取文本數(shù)據(jù)。 -
錯(cuò)誤處理:您可以使用 .catch()方法來捕獲任何請(qǐng)求或響應(yīng)的錯(cuò)誤。 -
使用 async/await:如果需要,您還可以使用async/await來更清晰地處理異步操作。
Fetch API 的特性和簡單的語法使它在許多前端項(xiàng)目中成為首選工具。然而,它也有一些限制,例如不支持同步請(qǐng)求,因此需要謹(jǐn)慎使用。
fetch("https://api.baidu.com/test")
.then(response => {
if (!response.ok) {
throw new Error("請(qǐng)求失敗,狀態(tài)碼:" + response.status);
}
return response.json();
})
.then(data => {
// 請(qǐng)求成功,處理響應(yīng)數(shù)據(jù)
console.log("成功獲取數(shù)據(jù):", data);
})
.catch(error => {
// 請(qǐng)求失敗,處理錯(cuò)誤
console.error(error);
});
XHR 和 Fetch 的對(duì)比
XHR 和 Fetch 都用于進(jìn)行 HTTP 請(qǐng)求,但它們之間存在一些關(guān)鍵區(qū)別:
-
語法: Fetch 使用 Promise,更直觀和易于理解。 -
跨域請(qǐng)求: Fetch 在跨域請(qǐng)求方面更靈活,支持 CORS。 -
流式傳輸: Fetch 支持可讀流,適用于大文件下載。 -
維護(hù)性: Fetch 更容易維護(hù)和擴(kuò)展。
常用庫和插件
基于 XHR 封裝的庫
-
jquery[4]:一個(gè) JavaScript 庫,提供了用于處理 DOM 操作、事件處理和 XHR 請(qǐng)求的便捷方法。 -
axios[5]:一個(gè)流行的 HTTP 請(qǐng)求庫,基于 XHR 開發(fā),支持瀏覽器和 Node.js。
基于 fetch 封裝的庫
-
redaxios[6]:它具有與 axios 類似的 API,但更輕量級(jí)且適用于現(xiàn)代 Web 開發(fā)。 -
umi-request[7]:由 Umi 框架維護(hù)的網(wǎng)絡(luò)請(qǐng)求庫,提供了強(qiáng)大的攔截器、中間件和數(shù)據(jù)轉(zhuǎn)換功能。
總結(jié)
XMLHttpRequest (XHR) 和 Fetch API 都是前端開發(fā)中用于進(jìn)行數(shù)據(jù)請(qǐng)求的有力工具。XHR 在傳統(tǒng)項(xiàng)目中仍然有用,而 Fetch API 則在現(xiàn)代 Web 開發(fā)中越來越流行。具體選擇哪個(gè)工具取決于項(xiàng)目的需求和開發(fā)團(tuán)隊(duì)的偏好,希望本文對(duì)你有幫助!
作者:王絕境
鏈接:https://juejin.cn/post/7295551704816189467
來源:稀土掘金
回復(fù)“加群”,一起學(xué)習(xí)進(jìn)步
