📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗
🌻 近期刚转战 CSDN,会严格把控文章质量,绝不滥竽充数,欢迎多多交流~ 👍
文章目录
- 写在前面的话
- 背景技术
- 发明目的
- 技术方案
- 方案特征
- 总结陈词
写在前面的话
本篇文章分享一下公司实战开发中基于defineProperty
技术实现的一种前端运行时变量检测方案。
此文乃前端专栏第三篇,本来先补充一下企业实战常用的Vue、Axios、NodeJS
等技术栈,那考虑到基础内容涉及篇幅较多,还在整理,等完毕了再发送。
好,开始我们无所不能的JavaScript之旅!
背景技术
在网页开发过程中,JavaScript 代码段是各式各样错误出现的高发地区,其中,最常见的情况往往由变量不确定的赋值引起,除了显示地造成前端异常报错,也可能得到非预期的执行结果,导致用户体验不佳。例如,JS变量,被赋值为null 或 undefined,导致访问其属性或方法报错,又比如,变量被调用了不属于其自身类型的方法,如赋值了 Object 对象类型的变量,程序员预想其是 Array 类型,访问其 length 属性,得到了 undefined 的结果。
由于变量的赋值,往往是不可控的,大部分赋值数据可能是来源于后端接口返回的数据,导致造成异常情形较为隐蔽,当从代码上无法轻易识别,运行时出现情形也是偶发的,因此,开发阶段排查困难,等到线上环境暴露出来,就会造成不佳的用户体验。
发明目的
本方案发明的目的是基于 JavaScirpt 的 defineProperty 方式,根据插件式的思想,实现了一种前端运行时变量异常检测的方法。
待进行异常检测的前端页面,只需要引入该插件,通过调用内置的初始化方法,传入需要检测监听的变量,以及相应的模板配置参数,即可在页面运行时,捕获相应异常信息,并按需进行合理的提示和异常信息统计。
这种方式的优点就是解耦、易扩展、使用灵活、适配性强,不影响原有业务逻辑。
技术方案
本方案是基于插件化的设计理念,底层采用 JavaScirpt 的 Object.defineProperty(),完成对前端变量添加异常校验拦截处理的附加逻辑,在日常网页开发过程中,可以利用参考本方案实现低耦合、易扩展的变量验证方案,降低生产环境的前端错误几率。
一、校验插件的实现
1、首先,定义函数的入参列表,包含如下参数。
参数1:要监听的变量,可以是 JavaScript 对象或复杂嵌套对象;
参数2:要校验配置模板信息,可以是具体的一段配置 JSON,代表完整的配置信息,也可以是一个模板编码,代表从后端服务加载,或是传 null,代表走默认配置,具体的配置可参考“后端服务增强 - 校验模板配置”专栏;
参数3:后端服务配置,传递null,将默认代表只采用走本地前端模式,传递具体后端配置JSON,则代表会接入后端服务;
2、接着,定义方法体,主要基于 Object.defineProperty 实现,具体如下:
2.1、先遍历参数1传入的待监听变量,再遍历该变量对象的属性列表,分别为其绑定 set/get 等方法。
2.2、get 方法,代表访问变量对应属性的时候,需要执行的前置逻辑,我们为其附加的业务逻辑是,在 get 方法内部,判断属性值是否符合异常值范畴,是的话,执行相应提示或统计逻辑;
2.3、set 方法,代表针对变量进行相应属性赋值的时候,需要执行的前置逻辑,我们为其附加的业务逻辑是,在 set 方法内部,可以判断即将赋值的数据,判断是否符合异常值范畴,是的话,同上,执行相应提示或统计逻辑;
3、若开启了后端接口交互模式,则主要有两个交互场景,具体如下:
初始化接口的时候,将调用后端服务,获取准确的模板配置,入参是模板编码或当前页面路径,后端将根据具体配置,找寻到适合调用客户端页面的模板配置,并返回,再完成模板解析和加载工作。
触发监听,并且捕获异常值时,将调用后端服务,将异常信息传入后端接口,进行操作和分析等操作,具体的逻辑可参考“后端服务增强 - 异常信息收集统计”专栏;
4、将校验核心函数封装为 JavaScript 模块,仅对外开放核心初始化方法。同时,针对不同前端技术框架,提供不同的引入方式。
/**
* 校验插件启用校验 - 函数声明
*/
function startCheck(valObj, ruleConfig, serverConfig){
....
}
//参数1,待校验对象
let valObj = {
'a':'123',
'b':'345'
}
//参数2,要校验配置模板信息
let ruleConfig = {
'异常值范围':[null,undefined,0],
'错误提示效果': '弹窗',
...
}
//参数3,后端服务配置
let serverConfig = {
'异常接口地址':'http://xxxx',
'加载配置地址':'http://xxxx',
'是否上报异常': '是',
...
}
//例1:触发校验函数,较完善的入参
startCheck(valObj, ruleConfig, serverConfig)
//例2:触发校验函数,不启用后端服务
startCheck(valObj, ruleConfig)
//例3:触发校验函数,完全使用缺省配置
startCheck(valObj, null, null)
二、后端增强服务的实现
功能说明:后端服务部分对于用户而言是可选的,仅使用前端插件不借助后端服务也可以满足大部分需求,加入后端服务,主要用于插件能力的增强。
1、校验模板动态配置
说明:前端插件使用的异常值范围支持默认配置或指定传入,通常指定null、undefined、0 等典型值,不适合指定复杂的场景,并且是由代码显示传入,如果想要更强大的动态模板配置能力,可以引入后端服务,也支持按不同页面、更细粒度的指定校验模板和其他复杂的能力。
1)支持配置校验模板列表,每个校验模板包含但不限于如下元素:模板编码、模板名称、模板配置、默认标识、有效标识等,模板有唯一的编码,前端插件初始化时,可以传入具体模板编号,让对应模板生效,也可以在配置中指定生效页面。
2)模板配置,使用JSON结构维护,可配置的子属性如下:
2.1)异常值范畴,可以是Array或Object结构,可以指定具体异常值,例如undefined,并为其指定使用变量类型和变量白名单等内容;
2.2)配置生效页面,可以是Array或Object结构,用于指定该配置生效的页面列表,适用于前端插件初始化时,不指定具体模板编号的场景;
2.3)错误提示效果,可以支持出现异常效果时的提示效果,包含但不限于如下方式:“控制台打印”、“弹窗提示”,“仅传输后台”等;
2、异常信息收集统计
功能说明:后端服务除了支持校验模板配置外,也可以用于异常信息收集统计。
1)创建“异常信息收集表”和“异常统计分析表”,前者包含但不限于如下字段:唯一ID、异常变量、异常类型、异常变量值、异常所属页面、创建日期等,后者包含但不限于如下字段:唯一ID、异常变量、统计日期、统计次数等。
2)提供“异常信息收集接口”,前端插件可以将异常信息通过此接口,进行相应的异常信息存储,后端可以通过定时服务,将异常信息收集表中的数据,定期汇总到异常统计分析表中;
3)增加“异常信息收集与统计页面”,将收集到的信息进行展示,并按不同维度进行统计,方便用户进行分析异常,已处理的数据也支持相应标注;
3、后端服务集成方式
后端服务可以做成一个独立的服务,单独启动,启动后可以进入模板配置和异常信息收集页面,也可以提供“异常信息收集”、“模板列表调用”等相应接口给前端插件调用。
也支持外挂方式实现,以Java为例,可以开放Jar包方式,给各业务系统以Maven引用。
附图1:前端变量监听校验流程
上述流程说明:
1、根据项目所使用的前端技术类型,以合适的方式,在需要校验的页面引入本方案的校验插件;
2、在前端页面初始化的代码段,调用本方案的核心初始化方法,传入待校验的变量列表,并指定期望的定制化效果配置属性,包含但不限于:提示方式,校验级别与范围,是否对接后端统计服务等;
3、启动前端项目,正常进行页面操作,若执行到变量访问或赋值的流程,插件将监听到相应操作,会判断该操作是否属于异常范畴,若不符合,则执行原有业务逻辑,不会有任何影响;若符合,将在F12控制台或统计服务界面观察到错误信息,并给出相应指导意见,当然也可以根据配置,及时给出明显的错误提示;
4、若有接入后端服务,也会将信息存储到后端服务,后端服务可选增加定时器进行统计分析,并展示给用户,用户可以针对统计的异常,进行反馈处理;
方案特征
1、基于插件化的设计理念,底层采用 JavaScirpt 的 defineProperty(),完成对前端变量添加异常校验拦截处理的附加逻辑,在日常网页开发过程中,可以利用参考本方案实现低耦合、易扩展的变量验证方案,降低生产环境的前端错误几率;
2、对原有业务代码侵入较小,只需要简单的一两行代码,以较低代价在测试环境获得前端变量验证效果,弥补前端运行时代码检测的空白;
3、支持动态配置校验模板和异常统计分析的能力,开启后端服务后,获得更全面的功能,为异常发现到处理提供完整的生命周期闭环管理;
总结陈词
本篇文章分享一下公司实战开发中基于defineProperty
技术实现的一种前端运行时变量检测方案,提供了思路参考,各位看官按需借鉴,可以根据实际情况封装实现。
💗 后续会逐步分享企业实际开发中的实战经验,有需要交流的可以联系博主。