使用 axios 自定义 request

前后端分离的数据交互需要注意高效的交互方式,常用轮子有 axios。

主要模式是用使用顶层的 store 中的 state 存储 token,在每次请求中使用 token 发起请求,然后判断响应的状态返回状态信息。

request.js :

import axios from 'axios'
import { Message, MessageBox } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'
// create an axios instance
const service = axios.create({
baseURL: process.env.BASE_API, // api 的 base_url
timeout: 40000 // request timeout
})
// request interceptor
service.interceptors.request.use(
config => {
// Do something before request is sent
if (store.getters.token) {
// 让每个请求携带token-- ['X-Token']为自定义key 请根据实际情况自行修改
config.headers['admin-token'] = getToken()
}
return config
},
error => {
// Do something with request error
console.log(error) // for debug
Promise.reject(error)
}
)
// response interceptor
service.interceptors.response.use(
/** response => response,
* 下面的注释为通过在response里,自定义code来标示请求状态
* 当code返回如下情况则说明权限有问题,登出并返回到登录页
* 如想通过 xmlhttprequest 来状态码标识 逻辑可写在下面error中
* 以下代码均为样例,请结合自生需求加以修改,若不需要,则可删除
*/
response => {
const res = response.data
const typew = res.type
if (typew === 'application/vnd.ms-excel') {
return res
}
// 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了;
if (res.code === 'login' || res.code === 'role_not_exit') {
// 请自行在引入 MessageBox
//
MessageBox.confirm('你已被登出,请重新登录', '确定登出', {
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
store.dispatch('FedLogOut').then(() => {
location.reload() // 为了重新实例化vue-router对象 避免bug
})
})
// }
return Promise.reject(res)
} else if (res.code === 'no_permit') {
Message({
message: res.msg,
type: 'error',
duration: 3 * 1000
})
return Promise.reject(res)
} else {
return res
}
},
error => {
let response = {
msg: '系统发生异常,请重试或联系管理员',
status: 'system error',
code: 50000,
detail: error,
ok: false
}
if (error.response) {
if (error.response.status === 504) {
response = {
...response,
msg: `${error.response.status}:网关炸了!`
}
} else if (error.response.status === 404) {
response = {
...response,
msg: `${error.response.status}:请求未知路径!`
}
} else if (error.response.status === 403) {
response = {
...response,
msg: `${error.response.status}:权限不足,请联系管理员!`
}
} else if (error.response.status === 500) {
response = {
...response,
msg: `${error.response.status}:服务器发生异常,请重试或联系管理员!`
}
} else {
response = {
...response,
msg: `${error.response.status}:发生未知错误,请重试或联系管理员!`
}
}
} else {
response = {
...response,
msg: '请求无响应,请检查本地或联系管理员检查服务端网络连接状态'
}
Message({
type: 'error',
message: response.msg
})
}
return response
}
)
export default service

store/index.js :

import Vue from 'vue'
import Vuex from 'vuex'
import app from './modules/app'
import errorLog from './modules/errorLog'
import permission from './modules/permission'
import tagsView from './modules/tagsView'
import user from './modules/user'
import getters from './getters'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
app,
errorLog,
permission,
tagsView,
user
},
getters
})
export default store

getters.js :

const getters = {
sidebar: state => state.app.sidebar,
language: state => state.app.language,
size: state => state.app.size,
device: state => state.app.device,
visitedViews: state => state.tagsView.visitedViews,
cachedViews: state => state.tagsView.cachedViews,
token: state => state.user.token,
avatar: state => state.user.avatar,
name: state => state.user.name,
introduction: state => state.user.introduction,
status: state => state.user.status,
roles: state => state.user.roles,
roleName: state => state.user.roleName,
setting: state => state.user.setting,
permission_routes: state => state.permission.routes,
addRoutes: state => state.permission.addRoutes,
errorLogs: state => state.errorLog.logs
}
export default getters

utils/auth.js :

import Cookies from 'js-cookie'
const TokenKey = 'Admin-Token'
export function getToken() {
return Cookies.get(TokenKey)
}
export function setToken(token) {
return Cookies.set(TokenKey, token)
}
export function removeToken() {
return Cookies.remove(TokenKey)
}