發佈一個npm包,用於監控頁面中的全部API請求的狀態和結果

  在前端監控系統中,或者其餘場景下,若是咱們須要監控當前頁面下全部請求狀態。可能一般請求下,咱們會選擇在請求的回調中去處理。這種作法的缺點就是會侵入具體的業務代碼。在一般的監控中,監控部分的代碼和業務部分的代碼是分離的。此外,若是存在不少的請求須要被監聽,經過侵入具體業務代碼,爲了減小代碼的重複,也須要封裝監聽請求的邏輯。前端

  本文經過monkey patches的方法實現了一個request-interceptor包,能夠按需求監聽請求。git

  該npm包的項目地址爲:https://github.com/forthealll... 歡迎使用。github

  • 獲取API請求的狀態和結果
  • monkey patches實現監控XMLHttpRequest請求
  • monkey patches實現監控fetch請求

本文的原文在個人博客中:https://github.com/forthealll...ajax

歡迎starnpm


1、獲取API請求和結果

  獲取請求的方式包含了fetch和XMLHttpRequest。好比下面是一個XMLHttpRequest請求的例子:json

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來判斷請求的狀態以及獲得請求的響應結果:app

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

fetch請求也是同理,所以咱們須要合理的封裝監聽請求的邏輯。google

2、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();

3、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函數來取消全部監聽函數。

相關文章
相關標籤/搜索