带玩具逛街时突然按下按钮的故事,丰满的妺妺3伦理播放,新婚人妻不戴套国产精品,大肉大捧一进一出好爽视频百度

XMLHttpRequest與Fetch API

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

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

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

術(shù)語(yǔ) 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ù)語(yǔ)激勵(lì)了開發(fā)人員,并引起了流暢的 Web 2.0 體驗(yàn)爆炸式增長(zhǎng)。

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

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

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

0 (uninitialized) - 請(qǐng)求未初始化

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

2(loaded)- 請(qǐng)求收到

3(interactive)- 處理請(qǐng)求

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

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

Fetch

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

或者你可以使用 async/await:

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

開源會(huì)話重播

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 除了具有更清晰簡(jiǎn)潔的語(yǔ)法之外,還有其它幾個(gè)優(yōu)勢(shì)。

頭、請(qǐng)求和響應(yīng)對(duì)象

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

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

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

緩存控制

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

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

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

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

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

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

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

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

跨域控制

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

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

憑證控制

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

credentials 可以設(shè)置為:

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

'same-origin' —— 包含對(duì)同源 url 的請(qǐng)求的憑證

'include' —— 包含所有請(qǐng)求的憑證

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

重定向控制

默認(rèn)情況下,fetch() 和 XMLHttpRequest 都遵循服務(wù)器重定向。但是,fetch() 在第二個(gè)參數(shù) init 對(duì)象中提供了替代選項(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() 可以流式傳輸請(qǐng)求和響應(yīng)數(shù)據(jù),這是一項(xiàng)新技術(shù),流允許你在發(fā)送或接收時(shí)處理更小的數(shù)據(jù)塊。例如,你可以在完全下載前處理數(shù)兆字節(jié)文件中的信息,下面的示例將傳入的(二進(jìn)制)數(shù)據(jù)塊轉(zhuǎn)換為文本,并將其輸出到控制臺(tái)。在較慢的連接上,你會(huì)看到更小的數(shù)據(jù)塊在較長(zhǎng)的時(shí)間內(nèi)到達(dá)。

服務(wù)器端支持

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

第二輪:XMLHttpRequest 獲勝

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

進(jìn)度支持

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

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

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

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

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

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

超時(shí)支持

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

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

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

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

中止支持

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

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

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

更顯式的故障檢測(cè)

當(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)或請(qǐng)求被中斷時(shí),才會(huì)發(fā)生拒絕。

fetch() 的 Response 對(duì)象提供了 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ā)人員都會(huì)使用更新的 Fetch API,它的語(yǔ)法更簡(jiǎn)潔,比 XMLHttpRequest 更有優(yōu)勢(shì);也就是說,這些好處中的許多都有特定的用例,但在大多數(shù)應(yīng)用程序中都不需要它們。只有兩種情況下 XMLHttpRequest 仍必不可少:

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

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

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


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

    評(píng)論

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

    評(píng)論

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

    推薦評(píng)論

    暫無評(píng)論哦,快來評(píng)論一下吧!

    全部評(píng)論(0條)

    主站蜘蛛池模板: 蒙阴县| 彭山县| 山西省| 凤冈县| 长治市| 哈密市| 三都| 怀安县| 郎溪县| 安顺市| 金寨县| 北川| 永泰县| 海盐县| 哈密市| 鄂温| 蒙城县| 石首市| 拜泉县| 永寿县| 涞源县| 河东区| 定陶县| 江山市| 贺州市| 蓬溪县| 壶关县| 麻栗坡县| 肇源县| 达孜县| 自治县| 泰州市| 广东省| 华阴市| 河东区| 乌鲁木齐县| 华宁县| 余庆县| 莫力| 蓬安县| 大庆市|