JS如何实现监控微信小程序的原理

  介绍

这篇文章给大家分享的是有关JS如何实现监控微信小程序的原理的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

JS有什么特点

1, JS属于一种解释性脚本语言;2,在绝大多数浏览器的支持下,JS可以在多种平台下运行,拥有着跨平台特性;3,JS属于一种弱类型脚本语言,对使用的数据类型未做出严格的要求,能够进行类型转换,简单又容易上手;4,JS语言安全性高,只能通过浏览器实现信息浏览或动态交互,从而有效地防止数据的丢失;5,基于对象的脚本语言,JS不仅可以创建对象,也能使用现有的对象。

<强>原理

之前也做过浏览器web端的SDK数据埋点上报,其实原理大同小异:通过劫持原始方法,获取需要上报的数据,最后再执行原始方法,这样就能实现无痕埋点。

举个例子:我希望监控所有web页面的ajax请求,每次发送ajax,都需要在控制台打印出发送的url

平时我们开发,发送ajax一般用的都是封装好的库,例如jQuery, Axios等,然而这些库,底层仍然用的是浏览器原生的XMLHttpRequest对象,因此,我们只需要修改XMLHttpRequest对象即可

<强>注意:由于JS的灵活性,修改原生方法是一件很容易的事,然而并不鼓励这样做!

//,把这段代码放在所有JS代码之前,我们就实现了拦截ajax的需求   window.XMLHttpRequest.prototype.open =,(函数(originOpen), {   ,return 函数(方法,url,异步),{   ,,   console.log才能(& # 39;发送了ajax,网址是:,& # 39;,,url);      return 才能originOpen.apply(,,参数);   ,};   })(window.XMLHttpRequest.prototype.open);

在这个立即执行函数中,我们把原生的开放的方法通过originOpen暂时存储起来,然后在外面包裹一层函数,实现了打印输出url的功能,最后通过originOpen。应用让原生方法运行,这样就实现了无痕拦截。

<强>监控小程序

<强>拦截wx。请求

小程序的运行环境并没有窗口和文档对象,它只暴露了一个天气全局对象,发送网络请求则是通过wx。请求这个api,因此,这次我们需要拦截的就是wx。请求方法

我们试着更改一下wx。请求

wx.request =,()函数,{   ,console.log (& # 39; 66666 & # 39;);   }

这时控制台会报错TypeError:不能集属性要求# & lt; Object>=> const  des  Object.getOwnPropertyDescriptor(天气,& # 39;请求# 39;);//,des  {//,可配置:,真的,//,可列举的:,真的,//,得到:f (),//,集:未定义//,}

我们可以换种方式修改:

const  originRequest =, wx.request;   Object.defineProperty(天气,& # 39;请求# 39;,,{   ,可配置:没错,   ,可列举的:真的,   ,可写:没错,   ,价值:函数(),{   const 才能;config =,参数[0],| |,{};   const 才能;url =, config.url;   console.log才能(& # 39;发送了ajax,网址是:,& # 39;,,url);      return 才能originRequest.apply(,,参数);   ,}   });

这次就实现拦截功能了!

<强>监控异常

小程序的注册函数的应用有个全局的>应用程序({,onError:函数(err), {   console.log才能(& # 39;上报错误啦! & # 39;);   wx.request({才能   ,,,url: & # 39; http://monitor.com/monitor/error& # 39;   ,,数据:犯错   })才能   ,}   })   应用程序({//大敌;其他逻辑   })

不过需要注意的是:如果后续的程序重写了onError的话,将会导致之前注册的onError失效。

解决方法可以是:我们监控SDK可以暴露一个接口,让接入方自己在onError中调用我们的接口。

应用程序({   ,onError: function  (err), {   ,monitor.notifyError (err)   ,}   })

<>强上报数据

收集好需要的数据后,当然就要上报后台。怎么上报?当然还是用的wx。请求发送请求。

这里就容易出现一个死循环:如果用之前被我们包装过的天气。请求上报数据,那么上报数据这个ajax请求,也会被我们认为是普通的ajax请求,然后又会触发上报,这样来来回回,无穷无尽的发送上报数据。

<强>解决方法有多种,比如:

<强>方案1

可以在包装wx。请求的时候,判断发送的url如果是上报接口,那么就不再上报了。

const  originRequest =, wx.request;   Object.defineProperty(天气,& # 39;请求# 39;,,{   ,可配置:没错,   ,可列举的:真的,   ,可写:没错,   ,价值:函数(),{   const 才能;config =,参数[0],| |,{};   const 才能;url =, config.url;   if 才能;(url.indexOf (& # 39; http://monitor.com& # 39;),祝辞,1),{//,,,直接发送请求,不上报   ,,return  originRequest.apply(,,参数);   ,,}   console.log才能(& # 39;上报ajax数据啦! & # 39;);   wx.request({才能   ,,,url: & # 39; http://monitor.com/monitor/ajax& # 39;   ,,数据:config.data   })才能   return 才能originRequest.apply(,,参数);   ,}   });

JS如何实现监控微信小程序的原理