axios拦截器
axios拦截分为请求拦截和响应拦截。
首先要安装axios,一般我会在项目的src目录中,新建一个network文件夹,作为我们的网络请求模块,然后在里面新建一个http.js和一个api文件夹。http.js文件用来封装我们的axios,api文件夹用来统一管理我们的接口url。
一、对axios进行基础配置
import axios from 'axios'; // 该处引入axios模块
// 构建axios实例
const instance = axios.create({
baseURL: process.env.BASE_API, // 该处url会根据开发环境进行变化(开发/发布)
timeout: 10000 // 设置请求超时连接时间
})
在http.js中添加请求拦截和响应拦截。在请求拦截中,会给请求头添加token字段,还有loading动画的开启。在响应拦截中,可以做一些loading动画的关闭,还有可以根据后端返回的状态码,做一些检验token是否有效或者过期的操作。接着就是做一些axios进行的api接口的封装,这里我用到了async,await封装请求接口函数,这样可以将异步操作同步化操作,代码更加友好,避免回调地域的出现。
二、request请求拦截器
instance.interceptors.request.use(
config => {
console.log(config); // 该处可以将config打印出来看一下,该部分将发送给后端(server端)
config.headers.token = '该处可设置token内容';
return config // 对config处理完后返回,下一步将向后端发送请求
},
error => { // 当发生错误时,执行该部分代码
console.log(error); //调试用
return Promise.reject(error)
}
)
// 先导入vuex,因为我们要使用到里面的状态对象
// vuex的路径根据自己的路径去写
import store from '@/store/index';
// 请求拦截器
service.interceptors.request.use(
config => {
// 不传递默认开启loading
if (!config.hideloading) {
// 请求是是否开启loading
Toast.loading({
forbidClick: true
})
}
// 每次发送请求之前判断vuex中是否存在token
// 如果存在,则统一在http请求的header都加上token,这样后台根据token判断你的登录情况
// 即使本地存在token,也有可能token是过期的,所以在响应拦截器中要对返回状态进行判断
if (store.state.token) {
config.headers.token = store.state.token;
//有些接口是 config.headers.Authorization = token
}
return config
},
error => {
// do something with request error
console.log(error) // for debug
return Promise.reject(error)
}
)
三、response拦截器
instance.interceptors.response.use(
response => { // 该处为后端返回整个内容
const res = response.data; // 该处可将后端数据取出,提前做一个处理
if ('正常情况') {
return response // 该处将结果返回,下一步可用于前端页面渲染用
} else {
alert('该处异常');
return Promise.reject('error')
}
},
error => {
console.log(error),
return Promise.reject(error)
}
)
将axios实例导出,方便其他页面调用
export default instance
其他页面通过调用上述实例发送请求
import instance from '../xxx.js'; // 将实例导入
const qs=require('qs'); // 用于处理前端发送数据格式
const base = process.env.BASE_URL; // 该处根据开发环境变化
export const login = params => {
return instance.post(`${base}/login`, qs.stringify(params)).then(res => res.data)}
// 该处即可实现向后端发送请求,并将数据返回给调用该接口的位置
四、api统一管理
在api文件夹里面有一个index.js,以及多个根据模块划分的接口js文件。index.js是一个api的出口,其他js则用来管理各个模块的接口。
例如下面的article.js:
/**
* article模块接口列表
*/
import request from '@/network/http'; // 导入http中创建的axios实例
import qs from 'qs'; // 根据需求是否导入qs模块
const article = {
// 新闻列表
articleList () {
return request({
url: '/artical',
method: 'get',
params,
hideloading: false //设置不隐藏加载loading
})
},
// 新闻详情,演示
articleDetail (id, params) {
return request({
url: '/detail',
method: 'get',
params:{
goodsId
},
hideloading: true
})
},
// post提交
login (data) {
return request({
url:'/adduser',
method:'post',
data:qs.stringify(data), //注意post提交用data参数
hideloading: true
})
}
// 其他接口…………
}
export default article;
index.js代码:
/**
* api接口的统一出口
*/
// 文章模块接口
import article from '@/api/article';
// 其他模块的接口……
// 导出接口
export default {
article,
// ……
}
在组件中通过按需引入使用
import {article} from '@/api/index'
created(){
article.articleList().then(info=>{
if(info.code==200)
this.num=info.data
}
})
}
为了省去引入的步骤,方便api的调用,我们需要将其挂载到vue的原型上。在main.js中
import Vue from 'vue'
import App from './App'
import router from './router' // 导入路由文件
import store from './store' // 导入vuex文件
import api from './api' // 导入api接口
Vue.prototype.$api = api; // 将api挂载到vue的原型上复制代码
然后我们在组件中可以这么用
//无需导入
methods: {
onLoad(id) {
this.$api.article.articleDetail(id, {
api: 123
}).then(res=> {
// 执行某些操作
})
}
}