777精品出轨人妻国产,熟女av人妻一区二区三四区,国产精品无码中文在线av,美脚パンスト女教师在线观看

XMLHttpRequest與Fetch API

轉(zhuǎn)載 收藏 評論
舉報(bào) 2022-05-09

本文最初發(fā)布于 OpenReplay 博客,由 InfoQ 中文站翻譯并分享。

Ajax 是大多數(shù) web 應(yīng)用程序背后的核心技術(shù),它允許頁面向 web 服務(wù)發(fā)出異步請求,因此數(shù)據(jù)可以不經(jīng)過頁面往返服務(wù)器無刷新顯示數(shù)據(jù)。

術(shù)語 Ajax 不是一種技術(shù),相反,它指的是從客戶端腳本加載服務(wù)器數(shù)據(jù)的方法。多年來已經(jīng)引入了幾種選擇,目前有兩種主要方法,大多數(shù) JavaScript 框架使用其中一種或兩種。

在本文中,我們將研究早期 XMLHttpRequest 和現(xiàn)代 Fetch 的優(yōu)缺點(diǎn),以確定哪種 Ajax API 最適合你的應(yīng)用。

XMLHttpRequest

XMLHttpRequest 在 1999 年首次作為非標(biāo)準(zhǔn)的 Internet Explorer 5.0 ActiveX 組件出現(xiàn),微軟開發(fā)它是為了支持基于瀏覽器的 Outlook 版本,XML 是當(dāng)時(shí)最流行(或被宣揚(yáng))的數(shù)據(jù)格式,除此之外,XMLHttpRequest 還支持文本和尚未發(fā)明的 JSON。

Jesse James Garrett 在他 2005 年的文章《AJAX: Web 應(yīng)用程序的新方法》中提出了“AJAX”概念,那時(shí)谷歌郵箱和谷歌地圖等基于 AJAX 的應(yīng)用程序已經(jīng)存在,但是這個(gè)術(shù)語激勵(lì)了開發(fā)人員,并引起了流暢的 Web 2.0 體驗(yàn)爆炸式增長。

AJAX 是“Asynchronous JavaScript and XML”的縮寫,盡管嚴(yán)格地說,開發(fā)人員并不需要使用異步方法、JavaScript 或 XML。我們現(xiàn)在將通用的“Ajax”術(shù)語表示任何從服務(wù)器獲取數(shù)據(jù)、更新 DOM 而無需刷新整個(gè)頁面的客戶端過程。

所有主流瀏覽器都支持 XMLHttpRequest,并在 2006 年成為官方的 web 標(biāo)準(zhǔn)。下面是一個(gè)簡單的例子,從你的域 / 服務(wù) / 端點(diǎn)獲取數(shù)據(jù),然后在控制臺將 JSON 結(jié)果顯示為文本:

onreadystatechange 回調(diào)函數(shù)在請求的生命周期中運(yùn)行好幾次;XMLHttpRequest 對象的 readyState 屬性則返回當(dāng)前狀態(tài):

0 (uninitialized) - 請求未初始化

1(loading)- 服務(wù)器連接建立

2(loaded)- 請求收到

3(interactive)- 處理請求

4(complete)- 請求完成,響應(yīng)準(zhǔn)備就緒

在達(dá)到狀態(tài) 4 之前,幾個(gè)函數(shù)就可以做很多事情。

Fetch

Fetch 是一個(gè)現(xiàn)代基于 promise 的 Ajax 請求 API,首次出現(xiàn)于 2015 年,在大多數(shù)瀏覽器中都得到了支持。它不是基于 XMLHttpRequest 構(gòu)建的,并且用更簡潔的語法提供了更好的一致性。下面的 Promise 鏈函數(shù)與上面的 XMLHttpRequest 例子相同:

或者你可以使用 async/await:

Fetch 更清晰、更簡潔,并且經(jīng)常在 Service worker 中使用。

開源會話重播

OpenReplay 是 FullStory 和 LogRocket 的開源替代品,它通過回放用戶在你的應(yīng)用程序上的一切操作,并顯示每個(gè)問題的操作堆棧,提供完整的可觀察性。OpenReplay 是自托管的,可以完全控制你的數(shù)據(jù)。

快樂調(diào)試吧!現(xiàn)代的前端團(tuán)隊(duì) —— 開始自由地監(jiān)控你的 web 應(yīng)用程序。

第 1 回合:Fetch 獲勝

與陳舊的 XMLHttpRequest 相比,F(xiàn)etch API 除了具有更清晰簡潔的語法之外,還有其它幾個(gè)優(yōu)勢。

頭、請求和響應(yīng)對象

上面簡單 fetch() 示例中,使用一個(gè)字符串定義 URL 端點(diǎn),也可以傳遞一個(gè)可配置的 Request 對象,它提供了有關(guān)調(diào)用的一系列屬性:

Response 對象提供了對訪問所有詳細(xì)信息的類似訪問:

Headers 對象提供了一個(gè)簡單的接口來設(shè)置請求中的頭信息或獲取響應(yīng)中的頭信息:

緩存控制

在 XMLHttpRequest 中管理緩存具有挑戰(zhàn)性,你可能會發(fā)現(xiàn)有必要附加一個(gè)隨機(jī)查詢字符串值來繞過瀏覽器緩存,F(xiàn)etch 方法在第二個(gè)參數(shù) init 對象中內(nèi)置了對緩存的支持:

緩存可以設(shè)置為:

'default' —— 如果有一個(gè)新的 (未過期的) 匹配,則使用瀏覽器緩存;如果沒有,瀏覽器會發(fā)出一個(gè)帶條件的請求來檢查資源是否已改變,并在必要時(shí)會發(fā)出新的請求

'no-store' —— 繞過瀏覽器緩存,并且網(wǎng)絡(luò)響應(yīng)不會更新它

'reload' —— 繞過瀏覽器緩存,但是網(wǎng)絡(luò)響應(yīng)會更新它

'no-cache' —— 類似于'default',除了一個(gè)條件請求總是被做

'force-cache' —— 如果可能,使用緩存的版本,即使它過時(shí)了

'only-if-cached' —— 相同的 force-cache,除了沒有網(wǎng)絡(luò)請求

跨域控制

跨域共享資源允許客戶端腳本向另一個(gè)域發(fā)出 Ajax 請求,前提是該服務(wù)器允許 Access-Control-Allow-Origin 響應(yīng)頭中的源域;如果沒有設(shè)置這個(gè)參數(shù), fetch() 和 XMLHttpRequest 都會失敗。但是,F(xiàn)etch 提供了一個(gè)模式屬性,可以在第二個(gè)參數(shù)的 init 對象中設(shè)置‘no-cors’屬性。

這將返回一個(gè)不能讀取但可以被其它的 API 使用的響應(yīng)。例如,你可以使用 Cache API 存儲返回再之后使用,可能從 Service Worker 返回一個(gè)圖像、腳本或 CSS 文件。

憑證控制

XMLHttpRequest 總是發(fā)送瀏覽器 cookie,F(xiàn)etch API 不會發(fā)送 cookie,除非你顯式地在第二個(gè)參數(shù) init 對象中設(shè)置 credentials 屬性。

credentials 可以設(shè)置為:

'omit' —— 排除 cookie 和 HTTP 認(rèn)證項(xiàng) (默認(rèn))

'same-origin' —— 包含對同源 url 的請求的憑證

'include' —— 包含所有請求的憑證

請注意,include 是早期 API 實(shí)現(xiàn)中的默認(rèn)值,如果你的用戶可能運(yùn)行舊的瀏覽器,就得顯式地設(shè)置 credentials 屬性。

重定向控制

默認(rèn)情況下,fetch() 和 XMLHttpRequest 都遵循服務(wù)器重定向。但是,fetch() 在第二個(gè)參數(shù) init 對象中提供了替代選項(xiàng):

redirect 可以設(shè)置為:

'follow' —— 遵循所有重定向(默認(rèn))

'error' —— 發(fā)生重定向時(shí)中止(拒絕)

'manual' —— 返回手動(dòng)處理的響應(yīng)

數(shù)據(jù)流

XMLHttpRequest 將整個(gè)響應(yīng)讀入內(nèi)存緩沖區(qū),但是 fetch() 可以流式傳輸請求和響應(yīng)數(shù)據(jù),這是一項(xiàng)新技術(shù),流允許你在發(fā)送或接收時(shí)處理更小的數(shù)據(jù)塊。例如,你可以在完全下載前處理數(shù)兆字節(jié)文件中的信息,下面的示例將傳入的(二進(jìn)制)數(shù)據(jù)塊轉(zhuǎn)換為文本,并將其輸出到控制臺。在較慢的連接上,你會看到更小的數(shù)據(jù)塊在較長的時(shí)間內(nèi)到達(dá)。

服務(wù)器端支持

Deno 和 Node 18 中完全支持 Fetch,在服務(wù)器和客戶端使用相同的 API 有助于減少認(rèn)知成本,還提供了在任何地方運(yùn)行的同構(gòu) JavaScript 庫的可能性。

第二輪:XMLHttpRequest 獲勝

盡管存在缺陷,XMLHttpRequest 還是有一些技巧可以超越 ajax Fetch()。

進(jìn)度支持

我們可以監(jiān)控請求的進(jìn)度,通過將一個(gè)處理程序附加到 XMLHttpRequest 對象的進(jìn)度事件上。這在上傳大文件(如照片)時(shí)特別有用:

事件處理程序傳遞的對象有三個(gè)屬性:

lengthComputable —— 如果進(jìn)度可以計(jì)算,則設(shè)置為 true

total —— 消息體的工作總量或內(nèi)容長度

loaded —— 到目前為止完成的工作或內(nèi)容的數(shù)量

Fetch API 沒有提供任何方法來監(jiān)控上傳進(jìn)度。

超時(shí)支持

XMLHttpRequest 對象提供了一個(gè) timeout 屬性,可以將其設(shè)置為請求自動(dòng)終止前允許運(yùn)行的毫秒數(shù);如果超時(shí),就觸發(fā)一個(gè) timeout 事件來處理:

fetch() 中可以封裝一個(gè)函數(shù)來實(shí)現(xiàn)超時(shí)功能:

或者,你可以使用 Promise.race():

這兩個(gè)方法都不容易使用,另外請求將在后臺繼續(xù)運(yùn)行。

中止支持

運(yùn)行中的請求可以通過 XMLHttpRequest 的 abort() 方法取消,如有必要,可以附加一個(gè) abort 事件來處理:

你可以中止一個(gè) fetch(),但它不是那么直接,需要一個(gè) AbortController 對象:

當(dāng) fetch() 中止時(shí),catch() 塊執(zhí)行。

更顯式的故障檢測

當(dāng)開發(fā)人員第一次使用 fetch() 時(shí),假設(shè)一個(gè) HTTP 錯(cuò)誤,如 404 Not Found 或 500 Internal Server error 將觸發(fā) Promise 拒絕并運(yùn)行相關(guān)的 catch() 塊,這似乎是合乎邏輯的,但事實(shí)并非如此:Promise 成功地解決了這些響應(yīng),只有當(dāng)網(wǎng)絡(luò)沒有響應(yīng)或請求被中斷時(shí),才會發(fā)生拒絕。

fetch() 的 Response 對象提供了 status 和 ok 屬性,但并不總是顯式地需要檢查它們,XMLHttpRequest 更明確,因?yàn)閱蝹€(gè)回調(diào)函數(shù)處理每一個(gè)結(jié)果:你應(yīng)該在每個(gè)示例中都看到 stuatus 檢查。

瀏覽器支持

我希望你不必支持 Internet Explorer 或 2015 年之前的瀏覽器版本,但如果是這樣的話,XMLHttpRequest 是你唯一的選擇。XMLHttpRequest 也很穩(wěn)定的,API 不太可能更新。Fetch 比較新,還缺少幾個(gè)關(guān)鍵特性,雖然更新不太可能破壞代碼,但你可以期待一些維護(hù)。

應(yīng)該使用哪個(gè) API ?

大多數(shù)開發(fā)人員都會使用更新的 Fetch API,它的語法更簡潔,比 XMLHttpRequest 更有優(yōu)勢;也就是說,這些好處中的許多都有特定的用例,但在大多數(shù)應(yīng)用程序中都不需要它們。只有兩種情況下 XMLHttpRequest 仍必不可少:

你正在支持非常老的瀏覽器——這種需求會隨著時(shí)間的推移而下降。

你需要顯示上傳進(jìn)度條。Fetch 后續(xù)將會支持,但可能需要幾年的時(shí)間。

這兩種選擇都很有趣,值得詳細(xì)了解它們!


本文系作者授權(quán)數(shù)英發(fā)表,內(nèi)容為作者獨(dú)立觀點(diǎn),不代表數(shù)英立場。
轉(zhuǎn)載請?jiān)谖恼麻_頭和結(jié)尾顯眼處標(biāo)注:作者、出處和鏈接。不按規(guī)范轉(zhuǎn)載侵權(quán)必究。
本文系作者授權(quán)數(shù)英發(fā)表,內(nèi)容為作者獨(dú)立觀點(diǎn),不代表數(shù)英立場。
未經(jīng)授權(quán)嚴(yán)禁轉(zhuǎn)載,授權(quán)事宜請聯(lián)系作者本人,侵權(quán)必究。
本內(nèi)容為作者獨(dú)立觀點(diǎn),不代表數(shù)英立場。
本文禁止轉(zhuǎn)載,侵權(quán)必究。
本文系數(shù)英原創(chuàng),未經(jīng)允許不得轉(zhuǎn)載。
授權(quán)事宜請至數(shù)英微信公眾號(ID: digitaling) 后臺授權(quán),侵權(quán)必究。

    評論

    文明發(fā)言,無意義評論將很快被刪除,異常行為可能被禁言
    DIGITALING
    登錄后參與評論

    評論

    文明發(fā)言,無意義評論將很快被刪除,異常行為可能被禁言
    800

    推薦評論

    暫無評論哦,快來評論一下吧!

    全部評論(0條)

    主站蜘蛛池模板: 天镇县| 顺昌县| 临夏市| 卢湾区| 通州市| 宣武区| 廉江市| 稷山县| 随州市| 包头市| 佛教| 开封县| 玉山县| 南安市| 绩溪县| 新昌县| 迁西县| 隆子县| 喜德县| 绥宁县| 大洼县| 湟中县| 望城县| 阿拉善盟| 山阴县| 田东县| 新宾| 宝应县| 沙洋县| 麟游县| 买车| 安达市| 海盐县| 桐城市| 雅安市| 龙陵县| 岳池县| 云安县| 武夷山市| 阿荣旗| 定襄县|