vue封装axios和利用拦截器监控返回的token的变化和报错信息

一、axios的封装

点击此处查看axios官方文档

步骤一:安装axios进入vue-cli

npm install axios

步骤二:新建一个httpConfig文件下,创建两个js文件,一个作为axios拦截器用,一个封装接口

步骤三:在serviceAPI.config.js中封装所有的API接口

const BASEURL  = 'http://192.168.1.112/' //设定一个常量BASEURL,引号内的是接口地址
const URL ={
    mainPage:[{
        mainPage:BASEURL+'api/mainPage/getMainPage',//引号内的接口地址
        loginOn: BASEURL + 'api/system/login',//获取token
    }]

}
//外溢到其他组件
export default{
    URL
}

步骤三:在Http.js中封装axios拦截器

import axios from 'axios' //引入axios组件
import router from '../router'; //引入vue-router组件
import url from './serviceAPI.config' //引入serviceAPI接口


// request拦截器:对请求参数做监听和处理
axios.interceptors.request.use(

    config => {
        //从session storage中获取token
        let token = sessionStorage.getItem("token"); 
        //在每一个接口的请求头上增加一个token
        if (config.url == url.URL.login[0].loginOn) {
        } else {
   
            config.headers = {
                'Authorization': token
            }
        }
        return config;
    },
    error => {//请求错误处理
        return Promise.reject(error.response);
    }
);

// 添加response响应拦截器
axios.interceptors.response.use(function (response) {
    // console.log(response.headers.authorization);
    //如果token值发生改变的时候,替换token值
    if (response.headers.authorization) {
        sessionStorage.setItem("token", response.headers.authorization);
    }
    
    // 对响应数据做点什么
    return response;
}, function (error) {
    // 响应头发生错误发生的操作
    if (error.response.status) {
        switch (error.response.status) {
            // 在登录成功后返回当前页面,这一步需要在登录页操作。                
            // 401 token过期                
            // 登录过期对用户进行提示                
            // 清除本地token和清空sessionStorage的             
            // // 跳转登录页面                
            case 401:
                // 清除token                    
                localStorage.removeItem('token');
                // this.$message.error="token已过期";
                // store.commit('loginSuccess', null);                    
                // 跳转登录页面,并将要浏览的页面fullPath传过去,登录成功后跳转需要访问的页面
                router.replace({
                    path: '/login',
                    query: {
                        redirect: router.currentRoute.fullPath
                    }
                });
                this.$message.error("登入已经过期")

                break;
            // 404请求不存在                /*  */
            case 403:  
                Toast({
                    message: '没有当前操作的权限',
                    duration: 1500,
                    forbidClick: true
                });
                
                // 跳转登录页面,并将要浏览的页面fullPath传过去,登录成功后跳转需要访问的页面
                setTimeout(() => {
                    router.replace({
                        path: '/',
                        query: {
                            redirect: router.currentRoute.fullPath
                        }
                    });
                }, 1000);
                break;
            case 400:
                Toast({
                    message: '参数错误',
                    duration: 1500,
                    forbidClick: true
                });
                // localStorage.removeItem('token');                    
                // store.commit('loginSuccess', null);                    
                // 跳转登录页面,并将要浏览的页面fullPath传过去,登录成功后跳转需要访问的页面
                setTimeout(() => {
                    router.replace({
                        path: '/',
                        query: {
                            redirect: router.currentRoute.fullPath
                        }
                    });
                }, 1000);
                break;
            // 其他错误,直接抛出错误提示                
            default:
        }
        return Promise.reject(error.response);
    }
});
export default axios;

步骤四:在main.js中引入在分配到其他组件中

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue' //引入vue组件
import App from './App' // 引入APP.vue组件
import router from './router' //引入router组件
//引入Http.js拦截器
import axios from './httpConfig/Http'
//引入serviceAPI.config.js管理API接口
import URL from '@/httpConfig/serviceAPI.config.js'

Vue.config.productionTip = false
//把axios拦截器存入vue的变量$axios引用
Vue.prototype.$axios = axios
//把API接口管理URL存入vue的Globel变量中
Vue.prototype.GLOBAL = URL;
/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

步驟五:在子组件中引入接口

<template>
  <div id="app">
    <img src="./assets/logo.png">
    <router-view/>
  </div>
</template>

<script>
export default {
  name: 'App',
  data () {
    return {

    }
  },
  methods () {
    //URL.mainPage[0].loginOn接口,data是参数变量, header头部信息参数
    this.$axios.post(URL.mainPage[0].loginOn,data,header)
    .then( res =>{
    //接口请求成功后的回调
    } )
    .catch ( err => {
      //接口请求失败后的回调
    })
  }
}

</script>

<style>

</style>

拓展:怎么封装post和get

封装axios的get方法:

代码展示:

/* 
* axios:get方法封装 
* @param {String} url [请求的接口地址]
* @param {Object} params [请求时携带的参数]
*/
export function get(url,params) {
    return new Promise( (resolve,reject)=>{
        axios.get( url, {
           params:params
        } ).then( res => {
            resolve(res.data);
        }).catch( err => {
            reject(err.data);
        })
    } )
   }

封装axios的post方法:

post方法和get方法相比,提交params参数的时候需要通过node的qs模块进行序列化参数,没有序列化,可能造成后台拿不到前台提交的数据

/*
 *axios:post方法封装
 *@param {string} url [请求接口的地址]
 * @param {object} params [请求时携带的参数]
 * QS.stringify(params) 序列化请求时携带的参数
 * 
*/ 
export function post (url,params){
    return new Promise( (resolve,reject) =>{
        axios.post( url, QS.stringify(params) )
        .then( res => {
            resolve(res.data);
        } )
        .catch( err => {
            reject(err.data)
        } )
    } );
}

把axios get 和post方法引入到serviceAPI.config.js 管理公共接口

在serviceAPI.config中定义一个api的方法,这个方法有一个参数是p,p是作为前端向后端请求接口时候所需要携带的参数,通过export抛出post方法

提供一个公共API 接口: https://api.apiopen.top/Email...

import {get,post} from './Http' //引入axios的get 和post方法
/* 
*定义一个变量为p,p为所携带的参数
*/
export const api = p => post('https://api.apiopen.top/EmailSearch?number=1012002',p)

在各个子组件的引用

template>
  <div id="app">
    <img src="./assets/logo.png">
    <router-view/>
  </div>
</template>

<script>
  import{api} from "./httpConfig/serviceAPI.config";
export default {
  name: 'App',
  data () {
    return {

    }
  },
  methods: {
   test () {
     api() //api({data})//在api中需要请求的参数 
     .then ( res =>{
       //成功后返回的数据
       console.log(res)
     })
   }
  },
  mounted () {
    this.test() //调用test方法
  }
}

</script>

<style>

</style>
我来评几句
登录后评论

已发表评论数()

相关站点

热门文章