共计 3411 个字符,预计需要花费 9 分钟才能阅读完成。
在前端监控系统中,或者其他场景下,如果我们需要监控当前页面下所有请求状态。可能通常请求下,我们会选择在请求的回调中去处理。这种做法的缺点就是会侵入具体的业务代码。在通常的监控中,监控部分的代码和业务部分的代码是分离的。此外,如果存在很多的请求需要被监听,通过侵入具体业务代码,为了减少代码的重复,也需要封装监听请求的逻辑。
本文通过 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 函数来取消所有监听函数。