BUG 描述
登录页面,选择微信扫码登录,如果是没有绑定企业的微信账号,在微信扫码页面跳转回来的时候,登录页请求接口会返回 400 状态码,然后刷新页面再次请求接口返回 400 状态码,无限循环。
代码分析
前端所有的 http
请求全部封装在 request.js
内,每次请求都会走一遍这里面的代码,这里根据不同的 状态码
做了一些处理,经过长时间多人的反复修改,里面穿插了很多 业务处理
, 这个 BUG 就是由这部分代码所引起的。
// … 注释部分为与本次 BUG 分析无关的上下文相关代码
1 | // request.js 修复前代码 |
上面这段代码的大概意思是,所有的 http
请求返回 状态码 400
, 就让路由跳转到登录页,然后看下登录页的处理
1 | // login/index.vue |
在登录页,每次刷新页面或者进入页面,都会进入到
mounted
生命周期,执行里面代码,然后调用了getQRToken
方法,在这个方法内部判断路由的参数(query)来得知是否是微信登录,如果是的话执行相应的处理。而当我们用没有绑定微信企业的账号扫码登录,微信跳转回来的路径是
https://86yqy.com/login?user_token=4e411cf59c1ea7a9c04fdd9329492c3c
, 所以在getQRToken
方法中,将会执行带有user_token
的判断分支里。在
user_token
的判断分支里请求接口,由于微信账号没有绑定企业返回了400
, 而每个请求都会走request.js
, 返回400
的话request.js
又会让路由走回登录页。
目前的情况是,
request.js
让路由走回登录页,但是没有清除掉query
参数,所以导致从微信扫码登录页面跳转回来的路径是https://86yqy.com/login?user_token=4e411cf59c1ea7a9c04fdd9329492c3c
, 而request.js
的400状态码
让路由跳转回登录页,完整路径还是https://86yqy.com/login?user_token=4e411cf59c1ea7a9c04fdd9329492c3c
, 没有变,所以又会从生命周期开始重新走一遍,一直循环。
解决方案
在 request.js
内 400状态码
的处理,跳转回首页是对的,但是要把完整路由里面的 query
参数给清除掉,所以在上述第一段代码中使用 router.go('/login')
去往登录页就不合适了,因为它本身就在 /login
路由下,只是多了参数,所以要使用 router.replace('/login')
来将完整的路由 /login?user_token=4e411cf59c1ea7a9c04fdd9329492c3c
替换成 /login
1 | // request.js 修复后代码 |
额外优化
除了更换
router
的方法使用解决死循环BUG
, 这里还将第Notification
组件 更换成了MessageBox
组件,与其他状态码的表现保持统一整个
request.js
多处使用了router.go
、router.push
、router.replace
, 也就是说上面的问题,其实在很多地方都是有问题的,只是没有触发,基于代码的严谨性、统一性做了相应的更改。
后续待优化
request.js
本意是封装 http
请求, 最初也是这样做的,但是由于长时间的多人修改,穿插了业务代码,导致现状维护难度高,可读性差,逻辑混乱难以梳理,所以应该重新封装 request.js
,将 业务代码
抽取出来,单独维护, request.js
只负责提供 http
请求相关功能。