JavaScript如何攔截全局Fetch的請(qǐng)求與響應(yīng)詳解
前言
目前,團(tuán)隊(duì)采用了根路徑轉(zhuǎn)發(fā)的方式,將接口請(qǐng)求轉(zhuǎn)發(fā)到服務(wù)器上,實(shí)現(xiàn)了一定的解耦。然而,隨著團(tuán)隊(duì)后端策略的變化,現(xiàn)在希望前端直接請(qǐng)求一個(gè)新的接口域名,而不再經(jīng)過中間層的處理。在這種情況下,由于之前的代碼中沒有對(duì)接口請(qǐng)求進(jìn)行統(tǒng)一的封裝,需要考慮如何以最小的成本進(jìn)行遷移。
Fetch API簡介
Fetch API是一種用于進(jìn)行網(wǎng)絡(luò)請(qǐng)求和響應(yīng)的現(xiàn)代Web API。它提供了一種簡單、強(qiáng)大且靈活的方式來處理HTTP請(qǐng)求。在使用Fetch API時(shí),我們通常創(chuàng)建一個(gè)請(qǐng)求對(duì)象,然后使用fetch
函數(shù)發(fā)送請(qǐng)求,并處理返回的Promise。
// GET請(qǐng)求示例: fetch('https://your.api.com/data') .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); // POST請(qǐng)求示例: fetch('https://your.api.com/data', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ id: 123, name: 'admin' }), }) .then(response => response.json()) .then(data => console.log('POST Request:', data)) .catch(error => console.error('POST Request Error:', error));
總體來說,使用Fetch API發(fā)送GET和POST請(qǐng)求的基本是相似的,但在POST請(qǐng)求中需要額外處理請(qǐng)求方法和請(qǐng)求體的數(shù)據(jù)。
注意:尤其是其中 GET 請(qǐng)求代碼的極簡風(fēng)格,所以有時(shí)為了省事,直接就使用了fetch。這也為后面請(qǐng)求和響應(yīng)的以及錯(cuò)誤處理帶來不便性。有的伙伴可能會(huì)大面積的去改代碼,這樣不僅費(fèi)時(shí)間,而且還需要測試,
全局Fetch攔截的需求
在一些情況下,我們可能希望在整個(gè)應(yīng)用程序范圍內(nèi)攔截和處理所有的Fetch請(qǐng)求和響應(yīng)。這可能是為了添加全局的身份驗(yàn)證、記錄請(qǐng)求和響應(yīng)、處理錯(cuò)誤等目的。為了實(shí)現(xiàn)這一點(diǎn),我們可以使用window.fetch
來攔截全局的Fetch。
攔截請(qǐng)求
要攔截全局的Fetch請(qǐng)求,我們可以重寫window.fetch
方法。我們可以在這個(gè)方法中添加自定義的邏輯,然后調(diào)用原始的fetch
方法。下面是一個(gè)簡單的例子:
const originalFetch = window.fetch; window.fetch = function(url, options) { // 添加你的自定義邏輯 console.log('Intercepted request to:', url); // 調(diào)用原始的fetch方法 return originalFetch(url, options); }; // 使用攔截后的fetch fetch('https://api.example.com/data') .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error));
在上面的例子中,我們簡單地在攔截函數(shù)中輸出了請(qǐng)求的URL,并在最后調(diào)用了原始的fetch
方法。這樣,我們就能在每個(gè)全局的Fetch請(qǐng)求之前執(zhí)行自定義的邏輯。
攔截響應(yīng)
類似地,我們也可以攔截全局的Fetch響應(yīng)。這可以讓我們?cè)谔幚眄憫?yīng)之前添加一些通用的邏輯,比如檢查響應(yīng)的狀態(tài)碼、處理錯(cuò)誤等。
const originalFetch = window.fetch; window.fetch = function(url, options) { // 調(diào)用原始的fetch方法 return originalFetch(url, options) .then(response => { // 添加你的自定義響應(yīng)邏輯 console.log('Intercepted response from:', url); // 返回原始的響應(yīng) return response; }); }; // 使用攔截后的fetch fetch('https://api.example.com/data') .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error));
在這個(gè)例子中,我們?cè)跀r截函數(shù)中輸出了響應(yīng)的URL,并在最后返回了原始的響應(yīng)。這允許我們?cè)谔幚砣值腇etch響應(yīng)之前執(zhí)行自定義的邏輯。
處理錯(cuò)誤
在實(shí)際應(yīng)用中,我們還需要考慮到錯(cuò)誤處理。如果攔截過程中發(fā)生了錯(cuò)誤,我們應(yīng)該能夠適當(dāng)?shù)靥幚硭鼈?,以避免?duì)應(yīng)用程序的其他部分造成負(fù)面影響。
const originalFetch = window.fetch; window.fetch = function(url, options) { try { // 添加你的自定義請(qǐng)求邏輯 console.log('Intercepted request to:', url); // 調(diào)用原始的fetch方法 return originalFetch(url, options) .then(response => { // 添加你的自定義響應(yīng)邏輯 console.log('Intercepted response from:', url); // 返回原始的響應(yīng) return response; }) .catch(error => { // 處理全局Fetch響應(yīng)錯(cuò)誤 console.error('Intercepted response error:', error); throw error; }); } catch (error) { // 處理全局Fetch請(qǐng)求錯(cuò)誤 console.error('Intercepted request error:', error); return Promise.reject(error); } }; // 使用攔截后的fetch fetch('https://api.example.com/data') .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error));
在上述例子中,我們使用了try
和catch
塊來捕獲可能發(fā)生的錯(cuò)誤,并進(jìn)行相應(yīng)的處理。這有助于確保全局Fetch攔截不會(huì)導(dǎo)致應(yīng)用程序的崩潰或不穩(wěn)定。
附:fetch/xhr和其他請(qǐng)求的區(qū)別
fetch/xhr和其他請(qǐng)求(如axios、ajax等)之間的主要區(qū)別在于它們的使用方式和一些功能上的不同。
首先,fetch是一種基于Promise的現(xiàn)代化網(wǎng)絡(luò)請(qǐng)求API,而xhr是一種傳統(tǒng)的XMLHttpRequest對(duì)象。fetch API基于新的web標(biāo)準(zhǔn),可以更好地處理請(qǐng)求和響應(yīng),支持更多現(xiàn)代化的功能,而xhr則是老舊的方式。
另一個(gè)區(qū)別在于fetch API返回的是一個(gè)Promise對(duì)象,可以使用Promise的鏈?zhǔn)秸{(diào)用和async/await語法,非常方便處理異步操作。而xhr則需要使用回調(diào)函數(shù)來處理異步操作,代碼結(jié)構(gòu)可能相對(duì)復(fù)雜。
此外,fetch API默認(rèn)情況下不會(huì)攜帶cookie信息,需要設(shè)置credentials屬性為"include"才能發(fā)送cookie。而xhr默認(rèn)會(huì)發(fā)送cookie信息,需要手動(dòng)設(shè)置xhr.withCredentials屬性為true來禁止發(fā)送cookie。
另外,fetch API在默認(rèn)情況下只會(huì)拒絕請(qǐng)求錯(cuò)誤的狀態(tài)碼(如404或500等),而不會(huì)拒絕其他的網(wǎng)絡(luò)錯(cuò)誤(如網(wǎng)絡(luò)超時(shí))。這意味著需要手動(dòng)檢查并處理網(wǎng)絡(luò)錯(cuò)誤。而xhr則可以通過onerror事件來處理所有類型的網(wǎng)絡(luò)錯(cuò)誤。
最后,fetch API在使用上可能相對(duì)簡單,語法更加直觀。而xhr則相對(duì)復(fù)雜,需要手動(dòng)設(shè)置請(qǐng)求頭、處理請(qǐng)求和響應(yīng)等。
總結(jié)起來,fetch/xhr和其他請(qǐng)求的主要區(qū)別在于使用方式、功能支持和代碼結(jié)構(gòu)等方面。fetch提供了更現(xiàn)代化、更簡潔的API,支持Promise和async/await語法,但xhr仍然是一種可靠和廣泛使用的老舊方式。
總結(jié)
到此這篇關(guān)于JavaScript如何攔截全局Fetch的請(qǐng)求與響應(yīng)的文章就介紹到這了,更多相關(guān)js攔截全局Fetch請(qǐng)求和響應(yīng)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
原生javascript實(shí)現(xiàn)讀寫CSS樣式的方法詳解
最近學(xué)習(xí)中遇到這個(gè)問題,為了日后方便查詢,本人翻閱了一些資料總結(jié)了以下方法,僅限原生JS,如有不對(duì)的地方歡迎指出!只求大家看完覺得有學(xué)到點(diǎn)什么就OK了!下面這篇文章主要介紹了利用原生javascript實(shí)現(xiàn)讀寫CSS樣式的方法,需要的朋友可以參考下。2017-02-02web頁面和微信小程序頁面實(shí)現(xiàn)瀑布流效果
這篇文章主要介紹了web頁面和微信小程序頁面實(shí)現(xiàn)瀑布流效果,本文通過實(shí)例代碼圖文介紹,給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2018-09-09js 點(diǎn)擊a標(biāo)簽 獲取a的自定義屬性方法
下面小編就為大家?guī)硪黄猨s 點(diǎn)擊a標(biāo)簽 獲取a的自定義屬性方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-11-11JS實(shí)現(xiàn)基本的網(wǎng)頁計(jì)算器功能示例
這篇文章主要介紹了JS實(shí)現(xiàn)基本的網(wǎng)頁計(jì)算器功能,涉及JavaScript事件響應(yīng)及數(shù)值運(yùn)算相關(guān)操作技巧,需要的朋友可以參考下2020-01-01Javascript 實(shí)現(xiàn)復(fù)制(Copy)動(dòng)作方法大全
現(xiàn)在瀏覽器種類也越來越多,諸如 IE、Firefox、Chrome、Safari等等,因此現(xiàn)在要實(shí)現(xiàn)一個(gè)js復(fù)制內(nèi)容到剪貼板的小功能就不是一件那么容易的事了。2014-06-06