在vue项目中,和后台交互获取数据这块,我们通常使用的是axios库,它是基于promise的http库,可运行在浏览器端和node.js中。他有很多优秀的特性,例如拦截请求和响应、取消请求、转换json、客户端防御XSRF等。
安装
npm install axios; // 安装axios
引入
首先,新建一个js文件用于引入axios。比如说,新建一个http.js文件,在文件中引入步骤如下所示:
import QS from 'qs';//引入qs模块,为post型数据提供序列化(非常重要)
import { Toast } from 'vant';
#设置请求超时
axios.defaults.timeout = 10000: //设置超时时间为10s```
#设置post请求方式请求头
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
设置请求拦截
首先,导入vuex。因为下面需要使用到里面的状态对象,用于实现登录认证功能。
代码如下:
config => {
const token = store.state.token;
token && (config.headers.Authorization = token);
return config;
},
error => {
return Promise.error(error);
})
注:在每次发送请求之前判断store中是否存在token,如果存在的话就将其添加到http请求的请求头当中去,用于后台通过token判断用户登录情况。同时,还存在一种情况是,token可能是过期的。所以在响应拦截器中要对返回状态进行判断。(响应拦截下面会讲到)
响应拦截
axios.interceptors.response.use(
response => {
if (response.status === 200) {
return Promise.resolve(response);
} else {
return Promise.reject(response);
}
},
error => {
if (error.response.status) {
switch (error.response.status) {
//请求返回的错误妈需要与后台开发人员协商好,以便更快的定位错误。
case 401: //用户未登录
router.replace({
path: '/login',
query: {
redirect: router.currentRoute.fullPath
}
});
break;
case 403: //token过期
Toast({
message: '登录已过期,请重新登录',
duration: 1000,
forbidClick: true
});
localStorage.removeItem('token');
store.commit('loginSuccess', null);
setTimeout(() => {
router.replace({
path: '/login',
query: {
redirect: router.currentRoute.fullPath
}
});
}, 1000);
break;
case 404: //请求错误
Toast({
message: '该请求不存在',
duration: 1500,
forbidClick: true
});
break;
default: // 其它错误,直接抛出错误提示
Toast({
message: error.response.data.message,
duration: 1500,
forbidClick: true
});
}
return Promise.reject(error.response);
}
}
});
/**
-
get方法,对应get请求
-
@param {String} url [请求的url地址]
-
@param {Object} params [请求时携带的参数]
*/export function get(url, params){ return new Promise((resolve, reject) =>{ axios.get(url, { params: params }).then(res => { resolve(res.data); }).catch(err =>{ reject(err.data) }) });}
post方法:原理同get基本一样,但是要注意的是,post方法必须要使用对提交从参数对象进行序列化的操作,所以这里我们通过node的qs模块来序列化我们的参数。这个很重要,如果没有序列化操作,后台是拿不到你提交的数据的。这就是文章开头我们import QS from ‘qs’;的原因。如果不明白序列化是什么意思的,就百度一下吧,答案一大堆。
/**
-
post方法,对应post请求
-
@param {String} url [请求的url地址]
-
@param {Object} params [请求时携带的参数]
*/export function post(url, params) { return new Promise((resolve, reject) => { axios.post(url, QS.stringify(params)) .then(res => { resolve(res.data); }) .catch(err =>{ reject(err.data) }) }); }
这里有个小细节说下,axios.get()方法和axios.post()在提交数据时参数的书写方式还是有区别的。区别就是,get的第二个参数是一个{},然后这个对象的params属性值是一个参数对象的。而post的第二个参数就是一个参数对象。两者略微的区别要留意哦!