axios对请求各种异常情况处理的封装方法
前端采用了axios来处理网络请求,为了避免在每次请求时都去判断各种各样的网络情况,比如连接超时、服务器内部错误、权限不足等等不一而足,我对axios进行了简单的封装,这里主要使用了axios中的拦截器功能。
封装后的网络请求工具js如下
import axios from 'axios' import { Toast } from 'mint-ui' //请求时的拦截 axios.interceptors.request.use(config => { return config; }, err => { Toast('请求超时!' ); return Promise.resolve(err); }) //响应时的拦截 axios.interceptors.response.use(data => { // 返回响应时做一些处理 // 第一种方式 const data = response.data // 根据返回的code值来做不同的处理(和后端约定) switch (data.code) { case '0': // 举例 // exp: 修复iPhone 6+ 微信点击返回出现页面空白的问题 if (isIOS()) { // 异步以保证数据已渲染到页面上 setTimeout(() => { // 通过滚动强制浏览器进行页面重绘 document.body.scrollTop += 1 }, 0) } // 这一步保证数据返回,如果没有return则会走接下来的代码,不是未登录就是报错 return data // 需要重新登录 case 'SHIRO_E5001': // 微信生产环境下授权登录 if (isWeChat() && IS_PRODUCTION) { axios.get(apis.mon.wechat.authorizeUrl).then(({ result }) => { location.replace(global.decodeURIComponent(result)) }) } else { // 否则跳转到h5登录并带上跳转路由 const search = encodeSearchParams({ next: location.href, }) location.replace(`/user/login?${search}`) } // 不显示提示消息 data.description = '' break default: } // 若不是正确的返回code,且已经登录,就抛出错误 const err = new Error(data.description) err.data = data err.response = response // 第二种方式,我采取的 if (data.status && data.status == 200 && data.data.status == 'error') { Toast(data.data.msg); return data; } return data; },err => { // 当响应异常时做一些处理 if (err && err.response) { switch (err.response.status) { case 400: err.message = '请求错误(400)'; break; case 401: err.message = '未授权,请重新登录(401)'; break; case 403: err.message = '拒绝访问(403)'; break; case 404: err.message = '请求出错(404)'; break; case 408: err.message = '请求超时(408)'; break; case 500: err.message = '服务器错误(500)'; break; case 501: err.message = '服务未实现(501)'; break; case 502: err.message = '网络错误(502)'; break; case 503: err.message = '服务不可用(503)'; break; case 504: err.message = '网络超时(504)'; break; case 505: err.message = 'HTTP版本不受支持(505)'; break; default: err.message = `连接出错(${err.response.status})!`; } } else { err.message = '连接服务器失败!' } Toast(err.message); return Promise.resolve(err); }) //如果需要可以封装一些请求的方法 let base = ''; export const postRequest = (url, params) => { return axios({ method: 'post', url: `${base}${url}`, data: params, transformRequest: [function (data) { let ret = '' for (let it in data) { ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&' } return ret }], headers: { 'Content-Type': 'application/x--form-urlencoded' } }); } export const uploadFileRequest = (url, params) => { return axios({ method: 'post', url: `${base}${url}`, data: params, headers: { 'Content-Type': 'multipart/form-data' } }); } export const putRequest = (url, params) => { return axios({ method: 'put', url: `${base}${url}`, data: params, transformRequest: [function (data) { let ret = '' for (let it in data) { ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&' } return ret }], headers: { 'Content-Type': 'application/x--form-urlencoded' } }); } export const deleteRequest = (url) => { return axios({ method: 'delete', url: `${base}${url}` }); } export const get = (url,params) => { return axios({ method: 'get', url: `${base}${url}?`, params: params, headers:{ 'Content-Type': 'application/x--form-urlencoded', 'Aess-Token': localStorage.getItem("AessToken") } }); }
封装之后的错误信息这个大家一目了然,没啥好说的,唯一要说的是当出错的时候我执行的是Promise.resolve(err);,而不是Promise.reject(err);
这是什么原因呢?因为封装axios一个重要的目的就是希望能够对错误进行统一处理,不用在每一次发起网络请求的时候都去处理各种异常情况,将所有的异常情况都在工具js中进行统一的处理。这种方式也带来一个问题,就是我在发起网络请求的时候,一般都会开启一个进度条,当网络请求结束时,不论请求成功还是失败,我都要将这个进度条关闭掉,而失败的处理我都统一写在工具js里边了,就没在请求失败时关闭进度条了,解决这个问题,有两种方案
1.直接在request的拦截器中开启一个fullscreen的loading,然后在response的拦截器中将其关闭,即我将进度条也封装到工具js中了,非常不推荐这种方式,因为这种方式的用户体验非常之差,有兴趣的小伙伴可以自己试一下就知道了。
2.第二种解决方案就是大家看到的,我返回一个Promise.resolve(err),则这个请求不会就此结束,错误的message我已经弹出来了,这条消息还是会继续传到then中,也就是说,无论请求成功还是失败,我在成功的回调中都能收到通知,这样我就可以将loading关闭了,比如狼蚁网站SEO优化这个登录请求
var _this = this; this.loading = true; this.postRequest('/login', { username: this.loginForm.username, password: this.loginForm.password }).then(resp=> { _this.loading = false; if (resp && resp.status == 200) { _this.getRequest("/config/hr").then(resp=> { if (resp && resp.status == 200) { var data = resp.data; _this.$store.mit('login', data); var path = _this.$route.query.redirect; _this.$router.replace({path: path == '/' || path == undefined ? '/home' : path}); } }) }
添加Vue插件
由于我对axios进行了封装,在每一个需要使用axios的地方,都需要导入相应的请求,略显麻烦,参考,我将请求方法挂到Vue上,具体操作如下
1.在main.js中导入所有的请求方法,如下
import {get} from './utils/api' import {postRequest} from './utils/api' import {deleteRequest} from './utils/api' import {putRequest} from './utils/api'
2.把它们添加到 Vue.prototype 上,如下
Vue.prototype.getRequest = getRequest; Vue.prototype.postRequest = postRequest; Vue.prototype.deleteRequest = deleteRequest; Vue.prototype.putRequest = putRequest;
如此之后,以后再需要发送网络请求,就不需要导入api了,直接通过狼蚁网站SEO优化这种方式即可
Post方法
this.postRequest('/login', { username: this.loginForm.username, password: this.loginForm.password }).then(resp=> { ... } });
GET方法
_this.get( this.url_s+"/Notice/findTotalCount",{ userId:localStorage.getItem("userid"), openId: localStorage.getItem('openId') } ) .then(function(res) { // })
以上这篇axios对请求各种异常情况处理的封装方法就是长沙网络推广分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持狼蚁SEO。
编程语言
- 如何快速学会编程 如何快速学会ug编程
- 免费学编程的app 推荐12个免费学编程的好网站
- 电脑怎么编程:电脑怎么编程网咯游戏菜单图标
- 如何写代码新手教学 如何写代码新手教学手机
- 基础编程入门教程视频 基础编程入门教程视频华
- 编程演示:编程演示浦丰投针过程
- 乐高编程加盟 乐高积木编程加盟
- 跟我学plc编程 plc编程自学入门视频教程
- ug编程成航林总 ug编程实战视频
- 孩子学编程的好处和坏处
- 初学者学编程该从哪里开始 新手学编程从哪里入
- 慢走丝编程 慢走丝编程难学吗
- 国内十强少儿编程机构 中国少儿编程机构十强有
- 成人计算机速成培训班 成人计算机速成培训班办
- 孩子学编程网上课程哪家好 儿童学编程比较好的
- 代码编程教学入门软件 代码编程教程