记录一次JS-SDK导致的线上生产事

117 阅读4分钟

记录一次JS-SDK导致的线上生产事故

问题说明:
1、首先本人是游戏h5sdk开发,入职新公司一个多月的时候对接的CP厂商给出反馈,sdk提供的接口无论穿什么参数提示的都是参数签名错误(sdk使用者调用sdk的方法,传递参数,sdk会对参数进行加密签名),此提示是后端返回,sdk代码是上一任开发者留下的,说明是前端传递的参数与后端解密得到的参数不一致。

解决过程:
1、判断是否是运营提供的密钥不正确,使用相同参数本地测试发现正常
2、sdk使用是否在请求前对密钥进行了修改,经过调试此可能排除
3、是否是前端传递的空对象{}被后端解析为[],因为后端是php,php的对象与数组相同,经过测试此可能排除
4、阅读上一任开发者留下的项目发现,他的引入axios、md5,pako等依赖的方式是直接将依赖的源码粘贴至自己的源码中,这有可能会导致依赖对象直接暴露在全局作用于下,根据这个可能查看CP厂商的游戏引用的js,发现有相同的pako依赖,console栏打印发现与本地的不相同,将原开发者的项目导入webpack中(原开发者没有使用任何模块化与工程化的内容),使用模块化开发(import引入依赖),打包上线,问题解决。

引发的后续问题:
第二天有用户反馈游戏无法登录,判断为是昨天更新的sdk的问题

解决过程:
1、后台查询用户信息用户的安卓系统为安卓9,属于旧系统,优化webpack打包配置,降低目标浏览器,因为公司没有该类型设备,最终决定更新上线,让用户进行测试,得到反馈依然无法进入游戏
2、询问该用户的手机品牌,发现为盗版手机,判断可能浏览器内核也是极其老旧的版本,于是本地写了一个测试demo进行打印错误信息以及用户的浏览器内核信息,将连接发给用户,发现正常打开,无任何任何报错。
3、在此忽略了用户手机浏览器与游戏的内核环境并不一致,于是寻求安卓开发的帮助,将demo进行打包发给用户,得到报错信息以及浏览器的版本,浏览器内核等于chrome66报错信息为thisGlobal不存在,找到解决方案,在webpack中使用插件将thisGlobal补齐,打包发现源码以及有处理thisGlobal的代码,打包上线,但是依旧无法解决
4、虽然阅读源码,发现源码中存在let、const、箭头函数等es6的内容,按理说这些应该被babel转译了才对,经过排除测试发现是babel在对代码进行转译的时候默认是不处理node_modules的,因为node_modules中的代码一般是转译过的,并且对node_modules的代码进行编译会消耗大部分时间,这里解决方案有几种 a.使用babel配置,对node_modules的代码进行单独编译处理 b.将依赖移出node_modules c.对依赖进行降低版本处理 看了一下原开发者的项目,最终选择降低版本,打包查看源码,let、const、箭头函等内容已经不存在,代码上线以及还是存在问题
5、接上述问题,根据报错提示查看源码发现是一段c=1n+2n,查阅资料发现BigInt类型是后续引入的类型,而babel对于此类型是不做处理,修改此处,报错解决,但是以及没解决问题,提示了新的问题 6、提示说Promise不存在,此时想起,babel-loader是不对es的api进行处理的,只对语法进行处理,处理新api需要使用corejs垫片进行垫平,加入垫片配置,打包上线问题解决,撒花!!!

在这里吐槽一下公司的代码,没有使用工程化的工具(webpack/vite),代码也没使用模块化,不使用git进行代码管理,没有修改分支只有主分支,命名随意,可谓是防御性编程属性拉满了

记录代码在旧版本浏览器的兼容性bug,希望可以帮助到遇到同样问题的人!