自从官方停止维护 vue resource之后,axios成为了大家与后端交互获取数据的最佳选择,做为vue官方推荐的http库,它有很多优秀特性,并且给开发者提供了很多二次开发的可能,关于更多,大家可以去查一下官方文档。
接下来我们说说项目中对axios常做的封装拦截:
安装axios
npm install axios
引入axios
封装的axios一般是在项目的 src 目录下边新建 request文件夹,新建一个request.js文件,内容如下:
// 引入axios
import axios from 'axios';
import Qs from 'qs'; // 这里的 qs是node的一个模块,用来序列化数据
import { Toast } from 'mint-ui'; // toast是mint-ui的提示组件,也可以使用其他UI库或者自定义
请求拦截
axios提供了interceptors供拦截处理,interceptors有两个拦截方式:
一是 axios.interceptors.request.use() 是发送请求之前的拦截,通过它我们可以设置api接口的一些东西,如根据环境不同设置不同域名、设置header 的cookie 值等等;
// 先导入vuex,因为我们要使用到里面的状态对象
// vuex的路径根据自己的路径去写
import store from '@/store/index';
// 请求拦截器
axios.interceptors.request.use(
config => {
// 每次发送请求之前判断vuex中是否存在token
// 如果存在,则统一在http请求的header都加上token,这样后台根据token判断你的登录情况
// 即使本地存在token,也有可能token是过期的,所以在响应拦截器中要对返回状态进行判断
const token = store.state.token;
token && (config.headers.Authorization = token);
return config;
},
error => {
return Promise.error(error);
})
另一个是axios.interceptors.response.use() 这是请求接口之后,对接口返回数据进行拦截。主要是方便统一处理请求返回的数据,可根据后端统一的接口文档进行处理,如正常返回数据是,status值为200,未登录时status值为400等等,后端接口报错也可以通过msg返回,在这里拦截,统一toast给用户。
// 响应拦截器
axios.interceptors.response.use(
response => {
// 如果返回的状态码为200,说明接口请求成功,可以正常拿到数据
// 否则的话抛出错误
if (response.status === 200) {
return Promise.resolve(response);
} else {
return Promise.reject(response);
}
},
// 服务器状态码不是2开头的的情况
// 这里可以跟你们的后台开发人员协商好统一的错误状态码
// 然后根据返回的状态码进行一些操作,例如登录过期提示,错误提示等等
// 下面列举几个常见的操作,其他需求可自行扩展
error => {
if (error.response.status) {
switch (error.response.status) {
// 401: 未登录
// 未登录则跳转登录页面,并携带当前页面的路径
// 在登录成功后返回当前页面,这一步需要在登录页操作。
case 401:
router.replace({
path: '/login',
query: {
redirect: router.currentRoute.fullPath
}
});
break;
// 403 token过期
// 登录过期对用户进行提示
// 清除本地token和清空vuex中token对象
// 跳转登录页面
case 403:
Toast({
message: '登录过期,请重新登录',
duration: 1000,
forbidClick: true
});
// 清除token
localStorage.removeItem('token');
store.commit('loginSuccess', null);
// 跳转登录页面,并将要浏览的页面fullPath传过去,登录成功后跳转需要访问的页面
setTimeout(() => {
router.replace({
path: '/login',
query: {
redirect: router.currentRoute.fullPath
}
});
}, 1000);
break;
// 404请求不存在
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);
}
}
});
封装了axios之后,还可以将接口们都统一管理起来
在src目录下新建 名为api的文件夹,里边可存放各个子项目的接口文件,新建 test1.js 来做例子:
test1.js:
import request from "../request/request.js";
// test1项目-详情页
export function getDetail() {
return request.post("/test1/getDetail");
}
然后,在项目中就可以将 getDetail 接口import进去使用拉,如下:
import { getDetail } from '@/src/api/test1.js'; // 路径是你自己的路径
各个项目分别新建文件保存,统一放在api文件夹下,方便后期统一管理,找起来也方便。