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(nowTime
axios可配置的一些选项,其他的具体看官网说明哈
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的封装(报错、鉴权、跳转、拦截、提示),希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!