
用 axios 拦截器统一处理 Token 和错误提示
最近在开发 QQ 机器人和它的管理面板,面板是前后端分离的,前端用 Vue.js + Axios + element-ui。
API 每次请求都需要带 Bearer Token,还要配置请求地址。如果每个页面发请求时都自己写一遍 header 和错误处理,重复很多,登录超时的处理也散在各处。于是我在 src/ 目录下新建了一个 axios-init.js,用于初始化 axios 并导出实例,把这些事集中在拦截器里做。
src/axios-init.js
import axios from 'axios'
import router from '@/router' //引入router
import cookies from 'vue-cookies'
import { Notification } from 'element-ui';
let instance = axios.create(); //创建Loading 的实例
instance.defaults.baseURL = "http://localhost/api/"; // 配置axios请求的地址
instance.defaults.headers.post['Content-Type'] = 'application/json; charset=utf-8';
axios.defaults.crossDomain = true;
axios.defaults.withCredentials = true; //设置cross跨域 并设置访问权限 允许跨域携带cookie信息
instance.defaults.headers.common['Authorization'] = ''; // 设置请求头为 Authorization
// 请求拦截器
instance.interceptors.request.use(
config => {
// 每次发送请求之前判断vuex中是否存在token
const token = cookies.get('token');
token && (config.headers.Authorization = 'Bearer '+ token);
return config;
},
error => {
return Promise.error(error); // 抛出错误
}
);
instance.interceptors.response.use(
response => {
// 如果返回的状态码为200,说明接口请求成功,可以正常拿到数据
// 否则的话抛出错误
// 如果返回的状态码和body中的code不一致,说明接口请求失败,抛出错误
if (response.status === 200 && response.data.code !== 200) {
switch (response.data.code) {
case 1001:
cookies.remove('token');
cookies.remove('userId');
cookies.remove('userName');
router.push({path: '/login'});
Notification({
title: '登录超时',
message: '请尝试重新登录',
type: 'warning'
});
break;
default:
Notification({
title: '提示',
message: response.data.message,
type: 'error'
});
}
return Promise.reject(response);
} else if (response.status === 200 && response.data.code === 200) {
return Promise.resolve(response);
}
},
error => {
// 如果请求失败,返回错误
return Promise.reject(error);
}
);
export default instance
axios.create() 创建一个独立的实例,baseURL、header 这些配置只挂在这个实例上。之后所有请求都走它,路径只写 /member/list 这种相对路径。
请求拦截器做的事只有一件:每次发请求之前从 cookie 里取出登录时存的 token,有就塞进 Authorization 头,格式是 Bearer <token>。
响应拦截器要多说两句。API 的约定是 HTTP 状态码都返回 200,业务结果放在 body 的 code 字段里,200 是成功。拦截器按 code 分三种情况:
- 200:正常返回,页面拿到数据
- 1001:登录超时。清掉 cookie 里的 token 和用户信息,跳到登录页,弹一个「登录超时」的警告通知
- 其他:把服务端返回的
message用 element-ui 的Notification弹出来,类型是 error
后两种都 Promise.reject,页面里的 .then 不会执行,页面也就不用再写一遍错误提示。
最后在 main.js 里引入导出的 instance,挂到 Vue 原型上。
src/main.js
import instance from "./axios-init";
Vue.prototype.$http = instance;
组件里用 this.$http.get('/xxx')、this.$http.post('/xxx', data) 发请求,Token 和错误提示都不用管。
头图/Cover
Photo by DS stories on Pexels
评论
评论加载中…