前端終止請(qǐng)求的3種方式總結(jié)(ajax、axios)
一、原生ajax終止請(qǐng)求
1、abort()
? XMLHttpRequest.abort()
方法用于終止 XMLHttpRequest
對(duì)象的請(qǐng)求,該方法沒有參數(shù),也沒有返回值。當(dāng)調(diào)用該方法時(shí),如果對(duì)應(yīng) XMLHttpRequest
對(duì)象的請(qǐng)求已經(jīng)被發(fā)送并且正在處理中,則會(huì)中止該請(qǐng)求;如果請(qǐng)求已經(jīng)完成(即已經(jīng)接收到完整的響應(yīng)),則不會(huì)執(zhí)行任何操作。而且調(diào)用該方法后,還會(huì)觸發(fā) XMLHttpRequest
對(duì)象的abort
事件,我們可以在該事件的處理函數(shù)中執(zhí)行后續(xù)相關(guān)邏輯代碼,例如清除請(qǐng)求相關(guān)數(shù)據(jù)等等。
? 當(dāng)一個(gè)請(qǐng)求被終止后,該請(qǐng)求的readyState
將會(huì)變?yōu)?code>0,并且status
屬性也會(huì)變?yōu)?code>0。
案例代碼:
// 創(chuàng)建XMLHttpRequest對(duì)象 const xhr = new XMLHttpRequest(); // 請(qǐng)求地址 const url = "https://developer.mozilla.org/"; // 初始化請(qǐng)求 xhr.open('GET', url, true); // 發(fā)送請(qǐng)求 xhr.send(); // 監(jiān)聽取消請(qǐng)求 xhr.addEventListener('abort', function () { console.log('請(qǐng)求被abort()取消了'); }); // 定時(shí)器模擬取消請(qǐng)求 setTimeout(() => { // 取消請(qǐng)求 xhr.abort(); // 取消請(qǐng)求之后的狀態(tài)status console.log('abort()之后的xhr.status---', xhr.status); // 取消請(qǐng)求之后的狀態(tài)readyState console.log('abort()之后的xhr.readyState---', xhr.readyState); }, 100);
執(zhí)行結(jié)果:
二、axios終止請(qǐng)求
1、AbortController(新版本)
? 在axiso
的0.22.0
版本開始,需要使用瀏覽器原生的AbortController
來終止請(qǐng)求,是目前推薦用的方法。當(dāng)使用該方法終止請(qǐng)求時(shí),如果對(duì)應(yīng)請(qǐng)求已經(jīng)被發(fā)送并且正在處理中,則會(huì)中止該請(qǐng)求;如果請(qǐng)求已經(jīng)完成(即已經(jīng)接收到完整的響應(yīng)),則不會(huì)執(zhí)行任何操作。
? 我們想監(jiān)聽到終止請(qǐng)求的操作,并進(jìn)行后續(xù)處理,有兩種方法:① 使用AbortController
提供的onabort
事件,通過監(jiān)聽該事件,并綁定事件處理函數(shù),在函數(shù)中進(jìn)行后續(xù)處理。② 使用try..catch
,終止請(qǐng)求之后,會(huì)觸發(fā)catch
,在catch
中進(jìn)行后續(xù)處理。如果同時(shí)使用onabort
事件和try..catch
,則會(huì)先觸發(fā)onabort
事件,再觸發(fā)try..catch
。
案例代碼:
// 以vue項(xiàng)目中使用axios為例 // 創(chuàng)建請(qǐng)求控制器 this.controller = new AbortController(); console.log("初始聲明的請(qǐng)求控制器------", this.controller); // 第一種方法:綁定事件處理程序 this.controller.signal.addEventListener("abort", () => { console.log("請(qǐng)求已終止,觸發(fā)了onabort事件"); // 進(jìn)行后續(xù)處理 }); // 第二種方法:try...catch try { // 發(fā)送文件上傳請(qǐng)求 const res = await this.$axios.post(api.Upload, uploadData, { timeout: 0, // 設(shè)置超時(shí)時(shí)間為 0/null 表示永不超時(shí) signal: this.controller.signal, // 綁定取消請(qǐng)求的信號(hào)量 }); } catch (error) { console.log("終止請(qǐng)求時(shí)catch的error---", error); // 判斷是否為取消上傳 if (error.message == "canceled"){ // 進(jìn)行后續(xù)處理 }; } // 終止請(qǐng)求 this.controller.abort(); console.log("終止請(qǐng)求后的請(qǐng)求控制器------", this.controller);
執(zhí)行結(jié)果:
? 注意:每個(gè)AbortController
可以同時(shí)取消多個(gè)請(qǐng)求,但是只能取消請(qǐng)求一次,一個(gè)AbortController
在終止過請(qǐng)求之后,其控制是否終止請(qǐng)求的signal.aborted
屬性會(huì)從false
,變?yōu)?code>true,目前本人沒找到恢復(fù)為false
的方法,暫且認(rèn)為是不可恢復(fù)的吧。如果后續(xù)請(qǐng)求還是綁定該請(qǐng)求控制器,則后續(xù)請(qǐng)求都會(huì)被提前終止,不會(huì)被發(fā)出。
? 如果我們想要在終止請(qǐng)求之后,不影響后續(xù)請(qǐng)求的正常發(fā)出,且后續(xù)請(qǐng)求也是可以被終止的,那么需要在每次發(fā)出請(qǐng)求之前,都通過構(gòu)造函數(shù)創(chuàng)建一個(gè)新的的 AbortController
,每次請(qǐng)求綁定的都是新的AbortController
,這樣才能做到多次請(qǐng)求之間不干擾。
2、CancelToken(舊版本)
? 在axiso
的0.22.0
之前的版本,需要使用取消令牌cancel token
來終止請(qǐng)求,不過該API從0.22.0
開始被棄用,目前已不建議再使用。當(dāng)使用該方法終止請(qǐng)求時(shí),如果對(duì)應(yīng)請(qǐng)求已經(jīng)被發(fā)送并且正在處理中,則會(huì)中止該請(qǐng)求;如果請(qǐng)求已經(jīng)完成(即已經(jīng)接收到完整的響應(yīng)),則不會(huì)執(zhí)行任何操作。
? 該方法只能通過try..catch
來監(jiān)聽取消請(qǐng)求操作,終止請(qǐng)求之后,會(huì)觸發(fā)catch
,在catch
中進(jìn)行后續(xù)處理。而且該方法在取消請(qǐng)求時(shí),可以通過參數(shù)自定義catch
的error
中的message
內(nèi)容。
案例代碼:
// 以vue項(xiàng)目中使用axios為例 // 這個(gè)地方需要導(dǎo)入原生的axios 最好不要使用二次封裝后的axios import axios from "axios"; // 創(chuàng)建請(qǐng)求令牌 this.source = axios.CancelToken.source(); console.log("初始聲明的請(qǐng)求令牌---", this.source); // 第二種方法:try...catch try { // 發(fā)送文件上傳請(qǐng)求 const res = await this.$axios.post(api.Upload, uploadData, { timeout: 0, // 設(shè)置超時(shí)時(shí)間為 0/null 表示永不超時(shí) cancelToken: this.source.token, // 綁定取消請(qǐng)求的令牌 }); } catch (error) { console.log("終止請(qǐng)求時(shí)catch的error---", error); // 判斷是否為取消上傳 if (error.message == "自定義取消請(qǐng)求的message"){ // 進(jìn)行后續(xù)處理 }; } // 終止請(qǐng)求 this.source.cancel("自定義取消請(qǐng)求的message"); console.log("取消請(qǐng)求后的請(qǐng)求令牌---", this.source);
執(zhí)行結(jié)果:
? 注意:該方法與AbortController
相同,都可以同時(shí)取消多個(gè)請(qǐng)求,但是只能取消請(qǐng)求一次,一個(gè)CancelToken
在終止過請(qǐng)求之后,如果后續(xù)請(qǐng)求還是綁定該請(qǐng)求令牌,則后續(xù)請(qǐng)求都會(huì)被提前終止,不會(huì)被發(fā)出。
? 同理,如果我們想要在終止請(qǐng)求之后,不影響后續(xù)請(qǐng)求的正常發(fā)出,且后續(xù)請(qǐng)求也是可以被終止的,那么需要在每次發(fā)出請(qǐng)求之前,都創(chuàng)建一個(gè)新的的 CancelToken
,每次請(qǐng)求綁定的都是新的CancelToken
,這樣才能做到多次請(qǐng)求之間不干擾。
三、參考資料
總結(jié)
到此這篇關(guān)于前端終止請(qǐng)求的3種方式的文章就介紹到這了,更多相關(guān)前端終止請(qǐng)求方式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
微信小程序?qū)崿F(xiàn)點(diǎn)擊按鈕后修改顏色
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)點(diǎn)擊按鈕后修改顏色,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12js 原生判斷內(nèi)容區(qū)域是否滾動(dòng)到底部的實(shí)例代碼
下面筆者就為大家分享一篇js 原生判斷內(nèi)容區(qū)域是否滾動(dòng)到底部的實(shí)例代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助2017-11-11實(shí)用的JS正則表達(dá)式(手機(jī)號(hào)碼/IP正則/郵編正則/電話等)
實(shí)用的JS正則表達(dá)式(手機(jī)號(hào)碼/IP正則/郵編正則/電話等),經(jīng)驗(yàn)積累,感興趣的朋友可以了解下,一定會(huì)對(duì)你有幫助的2013-01-01微信小程序使用第三方庫(kù)Underscore.js步驟詳解
大家都知道Underscore.js是一個(gè) JavaScript 工具庫(kù),它提供了一整套函數(shù)式編程的實(shí)用功能,但是沒有擴(kuò)展任何 JavaScript 內(nèi)置對(duì)象。那么這篇文章我們就來學(xué)習(xí)下微信小程序如何使用第三方庫(kù)Underscore.js,有需要的可以參考學(xué)習(xí)。2016-09-09JS實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn)并傳值
這篇文章主要為大家詳細(xì)介紹了JS實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn)并傳值,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-063種js實(shí)現(xiàn)string的substring方法
這篇文章主要介紹了3種javascript實(shí)現(xiàn)string的substring方法,需要的朋友可以參考下2015-11-11通過JS動(dòng)態(tài)創(chuàng)建一個(gè)html DOM元素并顯示
需要通過點(diǎn)擊某個(gè)元素后, 動(dòng)態(tài)創(chuàng)建一個(gè)DOM元素并顯示,因此寫了一些相關(guān)的js函數(shù),在此記錄下2014-10-10如何用JS模擬實(shí)現(xiàn)數(shù)組的map方法
這篇文章主要介紹了如何用JS模擬實(shí)現(xiàn)數(shù)組的map方法,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下2020-07-07javascript下使用Promise封裝FileReader
這篇文章主要介紹了javascript下使用Promise封裝FileReader,需要的朋友可以參考下2016-02-02