问题
- 登录时,填写错误的用户名密码,没有错误提示(没有进入catch分支)
- 获取ajax的返回结果比较麻烦:res.data.data.XXXX
目标
解决上面的两个问题
解决登录失败不报错的问题
背景知识:如下两种情况axios会主动抛出错误:
- 如果本次请求得到的响应的状态码 不是2开头的(如:400,500)
- 如果本次请求出现网络错误(如:断网,超时)
当我们提供错误的用户名和密码时,还是能从服务器获得到的数据,这个过程有如下两个特点:
- 本次网络请求的状态码是正常的(但是:success字段是false)
- 没有网络错误
所以axios并不会主动报错。如下图示
解决思路
在响应拦截器中,根据本次请求返回的数据中的success字段值,来决定是否主动抛出错误。
落地代码
在src/utils/request.js
中,补充响应拦截器如下:
// 响应拦截器 service.interceptors.response.use(response => { if (response.data.success) { // 操作成功 } else { // 如果success为false 业务出错,直接触发reject // 被catch分支捕获 return Promise.reject(new Error(response.data.message)) } }, error => { return Promise.reject(error) // 返回执行错误 让当前的执行链跳出成功 直接进入 catch })
解决获取有效数据代码冗余的问题
分析
观察api的返回结果,我们发现axios在处理接口返回值时,默认会自动给包裹一个data字段,这导致我们每次在业务模块获取数据都需要写res.data.data.xxxx
。
这样太麻烦了。
解决思路
在返回有效数据时,直接返回res.data
代码
在src/utils/request.js
中,对原有的响应拦截器进行修改。具体完成之后的代码如下:
// 响应拦截器 service.interceptors.response.use(response => { if (response.data.success) { // 操作成功 + return response.data } else { // 如果success为false 业务出错,直接触发reject // 被catch分支捕获 return Promise.reject(new Error(response.data.message)) } }, error => { return Promise.reject(error) // 返回执行错误 让当前的执行链跳出成功 直接进入 catch })
验收效果
- 验收登录成功的情况:再次登陆之后的查看结果,发现打印出来的已经直接是data中的数据了
- 验收登录失败的情况:输入一个错误密码,检查是否按照我们的设置显示出错误信息
小结
- 响应拦截器用来处理后端接口返回的数据---脱壳处理。
- 判断某个操作是否在业务是成功的,需要根据后端接口返回值中某个特殊字段(一般是由后端同学来约定)来判断,而不能只是依靠axios内置的报错机制