Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

发布一个npm包,用于监控页面中的所有API请求的状态和结果 #40

Open
forthealllight opened this issue Jan 17, 2019 · 1 comment

Comments

@forthealllight
Copy link
Owner

forthealllight commented Jan 17, 2019

发布一个npm包,用于监控页面中的所有API请求的状态和结果


  在前端监控系统中,或者其他场景下,如果我们需要监控当前页面下所有请求状态。可能通常请求下,我们会选择在请求的回调中去处理。这种做法的缺点就是会侵入具体的业务代码。在通常的监控中,监控部分的代码和业务部分的代码是分离的。此外,如果存在很多的请求需要被监听,通过侵入具体业务代码,为了减少代码的重复,也需要封装监听请求的逻辑。

  本文通过monkey patches的方法实现了一个request-interceptor包,可以按需求监听请求。

  该npm包的项目地址为:https://github.com/forthealllight/request-intercept 欢迎使用。

  • 获取API请求的状态和结果
  • monkey patches实现监控XMLHttpRequest请求
  • monkey patches实现监控fetch请求

一、获取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/forthealllight/request-intercept

本文只介绍如何使用,如有兴趣,可以读一读具体如何实现这个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函数来取消所有监听函数。

@forthealllight forthealllight changed the title 无侵入性的监控页面中的所有API请求的状态和结果 监控页面中的所有API请求的状态和结果 Jan 18, 2019
@forthealllight forthealllight changed the title 监控页面中的所有API请求的状态和结果 发布一个npm包,用于监控页面中的所有API请求的状态和结果 Jan 20, 2019
@vnues
Copy link

vnues commented Dec 8, 2020

hello,文章写的不错, 请问一下有微信吗 请求授权转载下文章

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants