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=> {
            // 执行某些操作      
        })    
    }  
}