【總結(jié)】2020- 前端常用的幾種請求方式
共 7991字,需瀏覽 16分鐘
·
2024-04-18 19:01
本文作者系360奇舞團前端開發(fā)工程師
前端數(shù)據(jù)請求方式主要包括XMLHttpRequest、Fetch、Axios、WebSocket等。這些請求方式各有特點,適用于不同的場景。本文將從綜合性能、優(yōu)缺點、最佳使用場景以及使用方式的角度對這些數(shù)據(jù)請求方式進行分析。
介紹
XMLHttpRequest(XHR)
XMLHttpRequest 是前端最早使用的數(shù)據(jù)請求方式。它支持異步請求,可以通過設(shè)置回調(diào)函數(shù)處理請求完成后的數(shù)據(jù)。
性能:XHR 在較早的瀏覽器中表現(xiàn)良好,但隨著瀏覽器性能的提升,其性能瓶頸逐漸凸顯。相較于其他請求方式,XHR 的性能稍遜一籌。
優(yōu)點:
-
廣泛的瀏覽器支持:盡管現(xiàn)代瀏覽器更推薦使用 Fetch API,但 XMLHttpRequest 仍然得到了幾乎所有瀏覽器的支持,包括一些較舊的版本。
-
事件驅(qū)動:XMLHttpRequest 使用事件驅(qū)動模型,提供了
onreadystatechange、onload、onerror等事件,可以方便地監(jiān)聽請求的不同階段。 -
支持上傳進度監(jiān)控:XMLHttpRequest 提供了
upload屬性,可以用來監(jiān)控文件上傳的進度。 -
支持請求和響應頭訪問:可以通過
setRequestHeader和getResponseHeader方法來設(shè)置和獲取請求和響應的頭信息。 -
支持超時設(shè)置:可以通過
timeout屬性設(shè)置請求的超時時間,并在超時后觸發(fā)ontimeout事件。 -
支持同步請求:雖然不推薦,但 XMLHttpRequest 支持同步請求,這在某些特定的場景下可能有用。
缺點:
-
語法復雜:相比于 Fetch API,XMLHttpRequest 的語法更加復雜,使用起來不夠直觀。
-
基于回調(diào):XMLHttpRequest 使用回調(diào)函數(shù)來處理響應,這可能導致回調(diào)地獄(callback hell),代碼難以維護。
-
不支持 Promise:XMLHttpRequest 不直接支持 Promise,需要手動封裝或使用第三方庫來實現(xiàn) Promise 風格的調(diào)用。
-
取消請求不夠優(yōu)雅:雖然 XMLHttpRequest 支持通過
abort方法取消請求,但這并不是一個優(yōu)雅的解決方案,因為它會導致請求被突然終止。 -
跨域問題:默認情況下,XMLHttpRequest 不支持跨域請求,需要服務器配置 CORS 頭或者在客戶端使用代理。
最佳使用場景:對于一些老舊項目或者需要與多種后端系統(tǒng)交互的場景,使用 XHR 可以保證兼容性。
使用方式:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://xxx', true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
var data = JSON.parse(xhr.responseText);
console.log(data);
}
};
xhr.send();
Fetch
Fetch 是一個現(xiàn)代的、基于 Promise 的 HTTP 客戶端,用于瀏覽器和 Node.js。它提供了一種更簡潔、更易于理解的方式來處理網(wǎng)絡(luò)請求。
性能:Fetch 在現(xiàn)代瀏覽器中性能較好,相較于 XHR 有所提升。
優(yōu)點
-
簡潔的語法:Fetch API 提供了一種更簡潔、更易讀的語法,使得發(fā)送請求和處理響應變得更加直觀。
-
基于 Promise:Fetch API 返回 Promises,這使得異步操作更加易于管理和鏈式調(diào)用。
-
內(nèi)置的錯誤處理:當網(wǎng)絡(luò)請求出現(xiàn)問題時,F(xiàn)etch API 會返回一個帶有錯誤狀態(tài)的 Promise,可以方便地使用
.catch()方法進行處理。 -
流式響應:Fetch API 支持流式響應,這意味著你可以處理正在下載的數(shù)據(jù),而不必等待整個響應體下載完成。
-
跨域支持:Fetch API 天然支持 CORS(跨源資源共享),使得跨域請求更加容易實現(xiàn)。
-
請求和響應對象:Fetch API 提供了 Request 和 Response 對象,這些對象可以讓你更容易地控制請求的行為和訪問響應的內(nèi)容。
缺點:
-
默認不攜帶 Cookie:Fetch API 在默認情況下不會發(fā)送同源的 Cookie,這可能導致一些基于 Cookie 的認證機制出現(xiàn)問題。可以通過設(shè)置請求的
credentials選項來解決這個問題。 -
不支持超時處理:Fetch API 本身不提供請求超時的功能。不過,可以通過包裝 Promise 來實現(xiàn)超時邏輯。
-
舊瀏覽器兼容性:Fetch API 在一些舊版本的瀏覽器中不被支持,可能需要使用 polyfill。
-
錯誤處理不夠直觀:Fetch API 不會將 HTTP 狀態(tài)碼為 4xx 或 5xx 的響應視為錯誤,這意味著你需要在
.then()方法中手動檢查響應狀態(tài)。 -
取消請求需要額外的 API:雖然 Fetch API 本身不支持取消請求,但可以通過結(jié)合使用
AbortController來實現(xiàn)。 -
上傳進度監(jiān)控:Fetch API 不提供上傳進度的監(jiān)控,而 XMLHttpRequest 支持。
最佳使用場景:現(xiàn)代瀏覽器中,需要簡潔語法和鏈式調(diào)用的場景。
使用方式:
fetch('https://xxx')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
Axios
Axios 是一個基于 Promise 的 HTTP 客戶端,用于瀏覽器和 Node.js。它擴展了 Fetch API,提供了更豐富的功能。
性能:Axios 在現(xiàn)代瀏覽器中性能較好,與 Fetch 相當。
優(yōu)點:
-
基于 Promise 的 API:Axios 使用 Promise,使得異步操作更加簡潔和易于管理,支持
.then和.catch方法。 -
攔截器支持:Axios 允許你添加請求和響應攔截器,這些攔截器可以在請求發(fā)送之前或響應到達之前進行自定義處理。
-
轉(zhuǎn)換請求數(shù)據(jù)和響應數(shù)據(jù):Axios 允許你在請求發(fā)送之前轉(zhuǎn)換請求數(shù)據(jù)(transformRequest)和在響應到達之前轉(zhuǎn)換響應數(shù)據(jù)(transformResponse)。
-
取消請求:Axios 支持取消請求,通過 CancelToken 實現(xiàn),這是 XMLHttpRequest 所缺乏的特性。
-
自動轉(zhuǎn)換 JSON 數(shù)據(jù):Axios 會自動將 JavaScript 對象轉(zhuǎn)換為 JSON 字符串當發(fā)送請求,并將響應中的 JSON 數(shù)據(jù)自動轉(zhuǎn)換為 JavaScript 對象。
-
客戶端支持防御 XSRF:Axios 提供了防御 XSRF(跨站請求偽造)的功能。
-
錯誤處理:Axios 提供了統(tǒng)一的錯誤處理機制,當請求失敗時,會在
.catch中捕獲到錯誤。 -
創(chuàng)建實例:Axios 允許創(chuàng)建實例,并在實例上設(shè)置默認配置,這對于多次請求使用相同配置非常有用。
缺點:
-
額外的依賴:使用 Axios 意味著你的項目將依賴于一個第三方庫,這可能會增加項目的復雜性。
-
瀏覽器兼容性:雖然 Axios 支持大多數(shù)現(xiàn)代瀏覽器,但不支持 IE9 及以下版本,如果你需要支持這些舊瀏覽器,可能需要引入額外的 polyfill。
-
體積:相比于原生 Fetch API,Axios 的體積更大,如果你只使用它的部分功能,可能會感覺不夠精簡。
-
學習曲線:對于初學者來說,Axios 提供了很多高級功能,這可能需要一個學習曲線來理解和正確使用它們。
-
社區(qū)和維護:雖然 Axios 很受歡迎,但它的維護和更新速度可能不如一些官方的 API 快,而且社區(qū)支持也可能有限。
最佳使用場景:需要在項目中進行大量 HTTP 請求,且需要豐富配置和取消請求功能的場景;易與 Vue.js 集成。
使用方式:
axios.get('https://xxx')
.then(response => {
console.log(response.data);
})
.catch(error => {
console.log('Error:', error);
});
WebSocket
WebSocket 是一種網(wǎng)絡(luò)通信協(xié)議,支持全雙工通信。在前端,WebSocket 主要用于與后端實時交互數(shù)據(jù)。
性能:WebSocket 提供了持續(xù)的 TCP 連接,減少了請求次數(shù),提高了性能。
優(yōu)點:
-
實時通信:WebSocket 提供了實時雙向通信的能力,服務器可以隨時向客戶端發(fā)送消息,這對于需要實時更新的應用(如實時聊天、游戲、實時數(shù)據(jù)監(jiān)控等)非常有用。
-
減少服務器負載:與傳統(tǒng)的輪詢(polling)或長輪詢(long polling)相比,WebSocket 減少了不必要的 HTTP 請求,從而減輕了服務器的負載。
-
保持連接狀態(tài):一旦 WebSocket 連接建立,連接會保持開放狀態(tài),直到客戶端或服務器關(guān)閉連接,這意味著不需要每次通信都重新建立連接。
-
輕量級協(xié)議:WebSocket 協(xié)議本身相對簡單,頭部開銷較小,這使得數(shù)據(jù)傳輸更加高效。
-
支持二進制數(shù)據(jù):WebSocket 不僅支持文本數(shù)據(jù),還支持二進制數(shù)據(jù),這對于需要傳輸圖像、音頻、視頻等二進制數(shù)據(jù)的應用非常有用。
缺點:
-
瀏覽器支持:盡管現(xiàn)代瀏覽器普遍支持 WebSocket,但一些較舊的瀏覽器可能不支持,這意味著你可能需要考慮兼容性問題。
-
服務器實現(xiàn)復雜:相比于基于 HTTP 的服務,實現(xiàn) WebSocket 服務器需要更多的邏輯來處理連接的維護、消息的廣播等。
-
需要額外的邏輯:WebSocket 本身并不提供消息的可靠傳輸,如果需要確保消息的可靠性,開發(fā)者需要自己實現(xiàn)重傳機制。
-
跨域問題:WebSocket 同樣受到同源策略的限制,跨域 WebSocket 連接需要服務器支持相應的 CORS(跨源資源共享)設(shè)置。
-
連接管理:WebSocket 連接需要有效管理,包括連接的建立、保持、重連和關(guān)閉等,這可能會增加應用的復雜性。
-
負載均衡器的支持:在使用 WebSocket 時,負載均衡器需要能夠處理長連接,這可能會限制某些云服務或代理服務器的使用。
最佳使用場景:需要實時交互數(shù)據(jù)的場景,如聊天應用、在線游戲等。
var socket = new WebSocket('ws://api.example.com/data');
socket.onopen = function(event) {
// 連接成功
};
socket.onmessage = function(event) {
// 收到消息
var data = JSON.parse(event.data);
console.log(data);
};
socket.onerror = function(error) {
// 連接出錯
console.log('Error:', error);
};
socket.onclose = function(event) {
// 連接關(guān)閉
};
性能比較
在比較性能時,需要考慮多個方面,包括執(zhí)行速度、內(nèi)存使用、兼容性、易用性和功能特性。下面是一個簡化的表格,概述了 XMLHttpRequest、Fetch API、Axios 和 WebSocket 這四種方式的性能比較:
| 特性/方式 | XMLHttpRequest | Fetch API | Axios | WebSocket |
|---|---|---|---|---|
| 執(zhí)行速度 | 中等 | 快 | 快 | 非常快(長連接) |
| 內(nèi)存使用 | 中等 | 低 | 低 | 低(長連接) |
| 兼容性 | 舊瀏覽器可能需要 ActiveXObject | 新瀏覽器 | 新瀏覽器,舊瀏覽器需要 polyfill | 新瀏覽器,舊瀏覽器需要 polyfill |
| 易用性 | 復雜的 API,基于回調(diào) | 簡潔的 API,基于 Promise | 簡潔的 API,基于 Promise,提供攔截器 | 簡單的 API,但需要處理連接管理和消息格式 |
| 功能特性 | 事件驅(qū)動,支持同步請求 | 基于 Promise,不支持同步請求 | 豐富的配置,攔截器,自動轉(zhuǎn)換 JSON | 實時雙向通信,不支持 HTTP 請求方法 |
| 跨域請求 | 需要服務器支持 CORS | 默認支持 CORS | 默認支持 CORS | 需要服務器支持 CORS |
| 取消請求 | 支持 abort 方法 |
結(jié)合 AbortController 使用 |
結(jié)合 AbortController 使用 |
通過關(guān)閉連接取消 |
| 自動轉(zhuǎn)換 JSON | 不支持 | 支持 | 支持 | 不支持,需要手動處理 |
最佳使用場景
-
XMLHttpRequest (XHR): 適用于需要廣泛兼容性的老舊系統(tǒng)或需要與多種后端系統(tǒng)交互的場景。
-
Fetch API: 適用于現(xiàn)代瀏覽器中,需要簡潔語法和鏈式調(diào)用的場景。
-
Axios: 適用于需要在項目中進行大量HTTP請求,且需要豐富配置和取消請求功能的場景,如與后端系統(tǒng)交互頻繁的單頁應用(SPA)。
-
WebSocket: 適用于需要實時交互數(shù)據(jù)的場景,如實時聊天應用、在線游戲等。
總結(jié):在選擇前端數(shù)據(jù)請求方式時,應根據(jù)項目的具體需求、兼容性要求以及性能考慮來決定使用哪種方法。每種方法都有其優(yōu)點和局限性,理解它們的特點,可以幫助開發(fā)者更好地構(gòu)建高效、穩(wěn)定的前端應用。
