1. 程式人生 > >vue登入攔截與請求/響應攔截

vue登入攔截與請求/響應攔截

登入攔截

在路由檔案 router.js 中引入 store.js

import store from '../store/store'

配置需要登入許可權的路由

   {
            path: '/main',
            meta: {
                requireAuth: true // 新增該欄位,表示進入這個路由是需要登入的
            },
            component: (resolve) => require(['../components/main'], resolve)
        },

在寫好的路由下方加上判斷該路由是否需要登入許可權

 ...

 router.beforeEach((to, from, next) => {
  if (to.meta.requireAuth) {  // 判斷該路由是否需要登入許可權
    console.log('beforeEach獲取當前的token是否存在  '+store.state.loginModule.token)
    if (store.state.loginModule.token) {  // 通過vuex state獲取當前的token是否存在
      next();
    }
    else {
      next({
        path: '/login',
        query: {redirect: to.fullPath}  // 將跳轉的路由path作為引數,登入成功後跳轉到該路由
      })
    }
  }
  else {
    next();
  }
 });

請求/響應攔截

新建一個 http.js 檔案

 import axios from 'axios'
 import store from './store/store'
 import * as types from './store/mutation_type'
 import router from './router/index'

 axios.defaults.timeout = 5000; // 超時時間
 //axios.defaults.baseURL = '';

 // http request 攔截器
 axios.interceptors.request.use(
    config => {
        if (store.state.token) {  // 判斷是否存在token,如果存在的話,則每個http header都加上token
            config.headers.Authorization = `token ${store.state.loginModule.token}`;
        }
        return config;
    },
    err => {
        return Promise.reject(err);
    });

 // http response 攔截器
 axios.interceptors.response.use(
    response => {
        return response;
    },
    error => {
        if (error.response) {
            switch (error.response.status) {
                case 401:
                    // 401 清除token資訊並跳轉到登入頁面
                    store.commit('loginOut');
                    router.replace({
                        path: 'login',
                        query: {redirect: router.currentRoute.fullPath}
                    })
            }
        }
        // console.log(JSON.stringify(error));//console : Error: Request failed with status code 402
        return Promise.reject(error.response.data)  // 返回介面返回的錯誤資訊
    });

 export default axios;

然後在 main.js 檔案中引入 http.js 檔案

 import Vue from 'vue'
 import App from './App'
 import router from './router'
 import store from './store/store'
 import axios from './http'

 Vue.config.productionTip = false

 /* eslint-disable no-new */
 new Vue({
   el: '#app',
   router,
   store,
   axios,
   template: '<App/>',
   components: { App }
 })

 

如果專案使用的是element-ui, http.js檔案可以這麼寫

// 引入axios以及element ui中的loading和message元件
  import axios from 'axios'
  import { Loading, Message } from 'element-ui'
  // 超時時間
  axios.defaults.timeout = 5000
  // http請求攔截器
  var loadinginstace
  axios.interceptors.request.use(config => {
    // element ui Loading方法
    loadinginstace = Loading.service({ fullscreen: true })
    return config
  }, error => {
    loadinginstace.close()
    Message.error({
      message: '載入超時'
    })
    return Promise.reject(error)
  })
  // http響應攔截器
  axios.interceptors.response.use(data => {// 響應成功關閉loading
    loadinginstace.close()
    return data
  }, error => {
    loadinginstace.close()
    Message.error({
      message: '載入失敗'
    })
    return Promise.reject(error)
  })

  export default axios

vue 懶載入

     {
      path: '/login',
      component: (resolve) => require(['../components/login'], resolve)
     }

vue頁面重新整理後,資訊為空

在路由檔案 router.js 中引入 mutation_type 檔案

  import * as type from '../store/mutation_type'

頁面重新整理時,重新賦值token

   // 頁面重新整理時,重新賦值token
  if (window.localStorage.getItem('token')) {
    store.commit('loginIn', window.localStorage.getItem('token')); // 得到token時需要存在本地
  }