Vue中axios的封装(报错、鉴权、跳转、拦截、提示)
- 统一捕获接口报错
- 弹窗提示
- 报错重定向
- 基础鉴权
- 表单序列化
实现的功能
- 统一捕获接口报错:用的axios内置的拦截器
- 弹窗提示:引入 ElementUI的 Message组件
- 报错重定向:路由钩子
- 基础鉴权:服务端过期时间戳和token,还有借助路由的钩子
- 表单序列化:我这边直接用 qs(npm模块),你有时间也可以自己写
用法及封装
用法
//服务层,import默认会找该目录下index.js的文件,这个可能有小伙伴不知道 //可以去了解npm的引入和es6引入的理论概念 importaxiosPluginfrom"./server"; Vue.use(axiosPlugin); 对axios的封装(AXIOS:index.js) importaxiosfrom"axios"; importqsfrom"qs"; import{Message}from"element-ui"; importrouterfrom"../router"; constAxios=axios.create({ baseURL:"/",//因为我本地做了反向代理 timeout:10000, responseType:"json", withCredentials:true,//是否允许带cookie这些 headers:{ "Content-Type":"application/x-www-form-urlencoded;charset=utf-8" } }); //POST传参序列化(添加请求拦截器) Axios.interceptors.request.use( config=>{ //在发送请求之前做某件事 if( config.method==="post" ){ //序列化 config.data=qs.stringify(config.data); //温馨提示,若是贵公司的提交能直接接受json格式,可以不用qs来序列化的 } //若是有做鉴权token,就给头部带上token //若是需要跨站点,存放到cookie会好一点,限制也没那么多,有些浏览环境限制了localstorage的使用 //这里localStorage一般是请求成功后我们自行写入到本地的,因为你放在vuex刷新就没了 //一些必要的数据写入本地,优先从本地读取 if(localStorage.token){ config.headers.Authorization=localStorage.token; } returnconfig; }, error=>{ //error的回调信息,看贵公司的定义 Message({ //饿了么的消息弹窗组件,类似toast showClose:true, message:error&&error.data.error.message, type:'error' }); returnPromise.reject(error.data.error.message); } ); //返回状态判断(添加响应拦截器) Axios.interceptors.response.use( res=>{ //对响应数据做些事 if(res.data&&!res.data.success){ Message({ //饿了么的消息弹窗组件,类似toast showClose:true, message:res.data.error.message.message ?res.data.error.message.message :res.data.error.message, type:"error" }); returnPromise.reject(res.data.error.message); } returnres; }, error=>{ //用户登录的时候会拿到一个基础信息,比如用户名,token,过期时间戳 //直接丢localStorage或者sessionStorage if(!window.localStorage.getItem("loginUserBaseInfo")){ //若是接口访问的时候没有发现有鉴权的基础信息,直接返回登录页 router.push({ path:"/login" }); }else{ //若是有基础信息的情况下,判断时间戳和当前的时间,若是当前的时间大于服务器过期的时间 //乖乖的返回去登录页重新登录 letlifeTime= JSON.parse(window.localStorage.getItem("loginUserBaseInfo")).lifeTime* 1000; letnowTime=newDate().getTime();//当前时间的时间戳 console.log(nowTime,lifeTime); console.log(nowTime>lifeTime); if(nowTime>lifeTime){ Message({ showClose:true, message:"登录状态信息过期,请重新登录", type:"error" }); router.push({ path:"/login" }); }else{ //下面是接口回调的satus,因为我做了一些错误页面,所以都会指向对应的报错页面 if(error.response.status===403){ router.push({ path:"/error/403" }); } if(error.response.status===500){ router.push({ path:"/error/500" }); } if(error.response.status===502){ router.push({ path:"/error/502" }); } if(error.response.status===404){ router.push({ path:"/error/404" }); } } } //返回response里的错误信息 leterrorInfo=error.data.error?error.data.error.message:error.data; returnPromise.reject(errorInfo); } ); //对axios的实例重新封装成一个plugin,方便Vue.use(xxxx) exportdefault{ install:function(Vue,Option){ Object.defineProperty(Vue.prototype,"$http",{value:Axios}); } };
路由钩子的调整(Router: index.js)
importVuefrom"vue"; importRouterfrom"vue-router"; importlayoutfrom"@/components/layout/layout"; //版块有点多,版块独立路由管理,里面都是懒加载引入 importcustomerManagefrom"./customerManage";//客户管理 importaccountfrom"./account";//登录 importadManagefrom"./adManage";//广告管理 importdataStatfrom"./dataStat";//数据统计 importloggerfrom"./logger";//日志 importmanagerfrom"./manager";//管理者 importputonManagefrom"./putonManage";//投放管理 importerrorfrom"./error";//服务端错误 import{Message}from"element-ui"; Vue.use(Router); //请跳过这一段,看下面的 constrouter=newRouter({ hashbang:false, mode:"history", routes:[ { path:"/", redirect:"/adver", component:layout, children:[ ...customerManage, ...adManage, ...dataStat, ...putonManage, ...manager, ...logger ] }, ...account, ...error ] }); //路由拦截 //差点忘了说明,不是所有版块都需要鉴权的 //所以需要鉴权,我都会在路由meta添加添加一个字段requireLogin,设置为true的时候 //这货就必须走鉴权,像登录页这些不要,是可以直接访问的!!! router.beforeEach((to,from,next)=>{ if(to.matched.some(res=>res.meta.requireLogin)){ //判断是否需要登录权限 if(window.localStorage.getItem("loginUserBaseInfo")){ //判断是否登录 letlifeTime= JSON.parse(window.localStorage.getItem("loginUserBaseInfo")).lifeTime* 1000; letnowTime=(newDate()).getTime();//当前时间的时间戳 if(nowTimeaxios可配置的一些选项,其他的具体看官网说明哈
exportdefault{ //请求地址 url:"/user", //请求类型 method:"get", //请根路径 baseURL:"http://www.mt.com/api", //请求前的数据处理 transformRequest:[function(data){}], //请求后的数据处理 transformResponse:[function(data){}], //自定义的请求头 headers:{"x-Requested-With":"XMLHttpRequest"}, //URL查询对象 params:{id:12}, //查询对象序列化函数 paramsSerializer:function(params){}, //requestbody data:{key:"aa"}, //超时设置s timeout:1000, //跨域是否带Token withCredentials:false, //自定义请求处理 adapter:function(resolve,reject,config){}, //身份验证信息 auth:{uname:"",pwd:"12"}, //响应的数据格式json/blob/document/arraybuffer/text/stream responseType:"json", //xsrf设置 xsrfCookieName:"XSRF-TOKEN", xsrfHeaderName:"X-XSRF-TOKEN", //下传和下载进度回调 onUploadProgress:function(progressEvent){ Math.round(progressEvent.loaded*100/progressEvent.total); }, onDownloadProgress:function(progressEvent){}, //最多转发数,用于node.js maxRedirects:5, //最大响应数据大小 maxContentLength:2000, //自定义错误状态码范围 validateStatus:function(status){ returnstatus>=200&&status<300; }, //用于node.js httpAgent:newhttp.Agent({keepAlive:true}), httpsAgent:newhttps.Agent({keepAlive:true}), //用于设置跨域请求代理 proxy:{ host:"127.0.0.1", port:8080, auth:{ username:"aa", password:"2123" } }, //用于取消请求 cancelToken:newCancelToken(function(cancel){}) };总结
这个封装虽说不是万金油版本,但是我感觉大多用axios结合vue的小伙伴,稍微改改都能直接拿来用
鉴权需要再严谨一些,比如token可以遵循JWT的规格,以及引入中间层nodejs(对传输的做拦截封装加解密,聚合接口);
以上所述是小编给大家介绍的Vue中axios的封装(报错、鉴权、跳转、拦截、提示),希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!