所謂web,即便你我素未謀面,便知志趣相投;足不出戶,亦知世界之大。git
如今的web應用,大都是經過請求(http)去獲取資源,拿到資源後再呈現給用戶,一個頁面中能夠有多個這樣的請求。每一次請求的開始,等待,完成,異常都會有相應的狀態來標識。咱們在本身的框架中一般都會使用一個全局過濾器,來攔截請求,目的大同小異:github
看看請求的整個流程圖:web
而咱們最經常使用的發送請求的即是XMLHttpRequest。瀏覽器
XMLHttpRequest.readyState的五種就緒狀態:服務器
而且XMLHttpRequest還提供了每一個階段的事件:網絡
若是請求停止,會觸發abort事件。數據結構
網絡錯誤(如太多重定向)會阻止請求完成,會觸發error事件。app
當事件完成,會觸發load事件。框架
當一個請求完成,不管成功(load)或者不成功(abort/error)後觸發ide
當調用send()時,觸發單個loadstart事件。
當等待服務器的響應時,XHR對象會發生progress事件。一般每隔50毫秒左右,因此可使用這事件給用戶反饋請求的進度。
當等待服務器的響應超時會觸發。
瞭解了XMLHttpRequest的請求流程後,咱們就能夠開始去攔截瀏覽器發出的請求,去作咱們想作的事。
方式一:
(function (xhr) { // Capture request before any network activity occurs: var send = xhr.send; xhr.send = function (data) { this.addEventListener('loadstart', onLoadStart); this.addEventListener('loadend', onLoadEnd); this.addEventListener('error', onError); return send.apply(this, arguments); }; })(XMLHttpRequest.prototype);
這種是最簡單直接的方式,修改XMLHttpRequest的原型,在發送請求時開啓事件監聽。大多數狀況下都是沒什麼大問題的,但後來發如今Angular4+以上版本中這樣去攔截,請求觸發loadend事件後獲取到的請求響應成功與否狀態始終爲false,由於Angualr2後來的版本也使用事件監聽來處理攔截,有些地方就衝突了。
方式二:
出現問題總要解決吧,而後就採用方法一的升級版本,徹底重寫XMLHttpRequest。
(function () { // create XMLHttpRequest proxy object var oldXMLHttpRequest = XMLHttpRequest; // define constructor for my proxy object window.XMLHttpRequest = function () { var actual = new oldXMLHttpRequest(); var self = this; this.onreadystatechange = null; // this is the actual handler on the real XMLHttpRequest object actual.onreadystatechange = function () { if (this.readyState == 1) { onLoadStart.call(this); } else if (this.readyState == 4) { if(this.status==200) onLoadEnd.call(this); else{ onError.call(this); } } if (self.onreadystatechange) { return self.onreadystatechange(); } }; // add all proxy getters ["status", "statusText", "responseType", "response", "readyState", "responseXML", "upload" ].forEach(function (item) { Object.defineProperty(self, item, { get: function () { return actual[item]; }, set: function (val) { actual[item] = val; } }); }); // add all proxy getters/setters ["ontimeout, timeout", "withCredentials", "onload", "onerror", "onprogress"].forEach(function (item) { Object.defineProperty(self, item, { get: function () { return actual[item]; }, set: function (val) { actual[item] = val; } }); }); // add all pure proxy pass-through methods ["addEventListener", "send", "open", "abort", "getAllResponseHeaders", "getResponseHeader", "overrideMimeType", "setRequestHeader", "removeEventListener" ].forEach(function (item) { Object.defineProperty(self, item, { value: function () { return actual[item].apply(actual, arguments); } }); }); } })();
如今咱們能夠放心的攔截瀏覽器發出的請求了,媽媽不再用擔憂個人學習了,哈哈。說一千道一萬,來點乾貨,直接看項目。
傳送門:web-monitor
喜歡請點個讚唄
或者去https://github.com/kisslove/w... Star一下
或者打賞一下
再或者……
哈哈,想法有點多了。