vue封裝axios和利用攔截器監控返回的token的變化和報錯信息

1、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方法:

在這裏插入圖片描述
代碼展現:vue

/* 
* 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模塊進行序列化參數,沒有序列化,可能形成後臺拿不到前臺提交的數據
在這裏插入圖片描述node

/*
 *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...webpack

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>

成功展現效果:
在這裏插入圖片描述
點擊此處跳轉到github查看源碼ios

相關文章
相關標籤/搜索