当前位置: 首页 > 后端技术 > Node.js

前端监控数据采集(请求拦截)

时间:2023-04-03 11:47:55 Node.js

所谓web,就算你我素不相识,也知道志同道合;足不出户,你就会知道世界的大小。01—为什么拦截请求目前的Web应用大多通过请求(http)获取资源,获取资源后呈现给用户。一个页面中可以有多个这样的请求。每个请求的开始、等待、完成、异常都会标记相应的状态。我们通常在自己的框架中使用全局过滤器来拦截请求。目的类似:发送请求前,修改请求参数,添加请求头,请求发送中进度计算(一般是文件上传),请求错误后捕获,请求结束后,处理后台返回适配的数据结构。看请求的整个流程图:XMLHttpRequest是最常用的发送请求的方法。XMLHttpRequest.readyState的五种就绪状态:0:请求未初始化(尚未调用open())。1:请求已建立,但尚未发送(尚未调用send())。2:请求已发送并正在处理(通常现在可以从响应中获取内容标头)。3:请求进行中;通常响应中有一些数据可用,但服务器尚未完成生成响应。4:响应完成;您可以获取并使用服务器的响应。并且XMLHttpRequest还提供了每个阶段的事件:abort如果请求中止,则会触发abort事件。error网络错误(例如太多重定向)将阻止请求完成,并且将触发error事件。load事件完成后,会触发load事件。loadend在请求完成时触发loadstart,无论是成功(加载)还是不成功(中止/错误)。调用send()时,会触发单个loadstart事件。progress在等待服务器响应时,XHR对象会触发一个progress事件。通常每50毫秒左右一次,因此您可以使用此事件向用户反馈请求的进度。timeout在等待服务器响应超时时触发。02—如何拦截请求了解了XMLHttpRequest的请求流程后,我们就可以开始拦截浏览器发送的请求,做我们想做的事情了。方法一:(function(xhr){//在任何网络活动发生之前捕获请求:varsend=xhr.send;xhr.send=function(data){this.addEventListener('loadstart',onLoadStart);this.addEventListener('loadend',onLoadEnd);this.addEventListener('error',onError);returnsend.apply(this,arguments);};})(XMLHttpRequest.prototype);这是修改XMLHttpRequestPrototype以在发送请求时启用事件监听的最简单直接的方法。大部分情况下是没有大问题的,但是后来发现在Angular4+以上的版本中用这种方式拦截,请求触发loadend事件后获取到的请求响应是否成功的状态始终为false,因为Angular2以后的版本也使用了事件监听来处理拦截,所以有些地方会发生冲突。方法二:一直解决问题,然后使用方法一的升级版,完全重写XMLHttpRequest。(function(){//创建XMLHttpRequest代理对象varoldXMLHttpRequest=XMLHttpRequest;//为我的代理对象定义构造函数window.XMLHttpRequest=function(){varactual=newoldXMLHttpRequest();varself=this;this.onreadystatechange=null;//这是真正的XMLHttpRequest对象的实际处理程序actual.onreadystatechange=function(){if(this.readyState==1){onLoadStart.call(this);}elseif(this.readyState==4){if(this.status==200)onLoadEnd.call(this);else{onError.call(this);}}if(self.onreadystatechange){returnself.onreadystatechange();}};//添加所有代理getters["status","statusText","responseType","response","re??adyState","responseXML","upload"].forEach(function(item){Object.defineProperty(self,item,{get:function(){returnactual[item];},set:function(val){实际[item]]=值;}});});//添加所有代理getter/setter["ontimeout,timeout","withCredentials","onload","onerror","onprogress"].forEach(function(item){Object.defineProperty(self,item,{get:function(){returnactual[item];},set:function(val){actual[item]=val;}});});//添加所有纯代理传递方法["addEventListener","send","open","abort","getAllResponseHeaders","getResponseHeader","overrideMimeType","setRequestHeader","removeEventListener"].forEach(function(item){Object.defineProperty(self,item,{value:function(){returnactual[item].apply(actual,arguments);}});});}})();你可以放心的拦截浏览器发送的请求,妈妈再也不用担心我的学习了。哈哈说千言万语,让我有点干货,直接看项目。传送门:如果你喜欢web-monitor,请点个赞或者上https://github.com/kisslove/w...Star或者打赏或者...哈哈,我脑洞大开。