釋出一個npm包,用於監控頁面中的所有API請求的狀態和結果
在前端監控系統中,或者其他場景下,如果我們需要監控當前頁面下所有請求狀態。可能通常請求下,我們會選擇在請求的回撥中去處理。這種做法的缺點就是會侵入具體的業務程式碼。在通常的監控中,監控部分的程式碼和業務部分的程式碼是分離的。此外,如果存在很多的請求需要被監聽,通過侵入具體業務程式碼,為了減少程式碼的重複,也需要封裝監聽請求的邏輯。
本文通過monkey patches的方法實現了一個request-interceptor包,可以按需求監聽請求。
該npm包的專案地址為:https://github.com/forthealll... 歡迎使用。
- 獲取API請求的狀態和結果
- monkey patches實現監控XMLHttpRequest請求
- monkey patches實現監控fetch請求
本文的原文在我的部落格中:https://github.com/forthealll...
歡迎star
一、獲取API請求和結果
獲取請求的方式包含了fetch和XMLHttpRequest。比如下面是一個XMLHttpRequest請求的例子:
var client = new XMLHttpRequest(); client.open("POST","http://10.12.72.16:8080/extraInfo" ); client.setRequestHeader("Content-Type", "application/json; charset=utf-8"); client.send(JSON.stringify({}));
通常我們會通過client上出發的readystatechange來判斷請求的狀態以及得到請求的響應結果:
client.onreadystatechange = function () { if (client .readyState==4 &&client.status==200) { console.log(client.responseText);// } }
XMLHttpRequest的prototype除了onreadystatechange事件外還有其他很多事件,比如onabout、onerror、onload、onloadstart等等事件。如果我們要完整的監聽一個請求,那麼需要實現完整的實現這些事件:
client.onabout = function(){} client.onerror = function(){} clinet.onload = function(){} client.onloadstart = function(){} ....
此外如果當某一個事件發生時,需要按順序的實行一系列的函式,這樣會使得事件函式內部越來越複雜,使得整體專案變的無法維護。
fetch請求也是同理,因此我們需要合理的封裝監聽請求的邏輯。
二、monkey patches實現監控XMLHttpRequest請求
本文不會具體介紹如何通過monkey patches來封裝監聽請求的邏輯,該邏輯已經在我的npm包中實現,具體可以參考我的開源專案:
https://github.com/forthealll...
本文只介紹如何使用,如有興趣,可以讀一讀具體如何實現這個monkey patches,在目錄的source資料夾中,如有疑問,可以提issue。
該npm包的包名為:req-interceptor。首先來看對於XMLHttpRequest請求如何使用:
import { ajaxIntercept } from 'req-interceptor'; //監聽 const unregister = ajaxIntercept.register({ requestAbout: function (xhr) { // xhr is real instance of a request console.log(xhr) }, requestError: function (xhr) { // xhr is real instance of a request console.log(xhr) }, requestLoad: function (xhr) { // xhr is real instance of a request console.log(xhr) }, }); //傳送請求 var client = new XMLHttpRequest(); client.open("POST","http://10.12.72.16:8080/extraInfo" ); client.setRequestHeader("Content-Type", "application/json; charset=utf-8"); client.send(JSON.stringify({}));
只需要在傳送請求前先呼叫ajaxIntercept.register函式傳入監聽的物件,該函式會返回一個取消監聽的方法。
這樣就監聽之後的任意請求,在ajaxIntercept.register中的實際引數的物件中,物件的屬性是一個函式,引數為xhr,xhr就是一個被監聽的XMLHttpRquest,因此我們可以從xhr中拿到請求的具體響應。xhr的一個例子為:
xhr = { readyState: 4 response: "{"success":0}" responseText: "{"success":0}" responseType: "" responseURL: "http://10.12.72.16:8080/extraInfo" responseXML: null status: 201 statusText: "Created" timeout: 0 }
如果我們在取消對於某一個請求的監聽,則呼叫該返回的
unregister函式,此後請求不會再被監聽。
unregister();
此外我們也可以在某一個請求前新增多個監聽函式:
import { ajaxIntercept } from 'req-interceptor'; //監聽 const unregister1 = ajaxIntercept.register({...}); const unregister2 = ajaxIntercept.register({...}); const unregister3 = ajaxIntercept.register({...}); //請求 client.open(url,....)
如果我們想要一次性移除所有的對於請求的監聽函式,可以直接呼叫:
ajaxIntercept.clear();
三、monkey patches實現監控fetch請求
對於fetch請求也是一樣的。
import { fetchIntercept } from 'req-interceptor'; import { fetchIntercept } from 'req-interceptor'; const unregister = fetchIntercept.register({ request: function (url, config) { // Modify the url or config here return [url, config]; }, requestError: function (error) { // Called when an error occured during another 'request' interceptor call return Promise.reject(error); }, response: function (response) { // Modify the reponse object return response; }, responseError: function (error) { // Handle an fetch error return Promise.reject(error); } }); // Call fetch to see your interceptors in action. fetch('http://google.com');
不同的是,fetch不像XMLHttpRequest請求那樣,可以監聽完整的過程,fetch只有request、requestError、response和responseError這4個屬性可以監聽,分別對映請求的引數,請求失敗,請求返回成功,請求返回失敗。
同樣的也可以通過返回函式來取消監聽,以及通過clear函式來取消所有監聽函式。