axios網絡請求(axios封裝、鑑權、攔截)

使用vue框架的小夥伴對於axios 確定是不陌生的。 網上一搜,介紹一大堆,axios中文文檔來自簡書這裏就再也不講他的原理阿用法之類了,直接上代碼。vue

1、仍是先安裝

這裏使用npm安裝,須要其餘安裝方法的自行看文檔:axios中文文檔來自簡書
npm install axios --saveios

2、直接使用 (request.js)
import axios from 'axios'  // 引入axios
import {refresh} from '@/api/user' // 封裝好的refresh(鑑權須要刷新)接口
import Vue from 'vue'
import Toast  from 'muse-ui-toast' // 根據業務選擇合適的ui庫,我這裏使用muse-ui的toast(消息框)組件
Vue.use(Toast)
// 建立axios實例
const service = axios.create({
  baseURL: process.env.NODE_ENV === 'production' ? '' : process.env.NODE_ENV === 'pre'? '' : 'http://127.0.0.1:8888',
  timeout: 15000 // 請求超時時間
})
// request攔截器
service.interceptors.request.use(config => {
  // Do something before request is sent
  let token = sessionStorage.getItem('access_token') // 個人用戶權限token存儲再sessionStorage中,可根據業務須要修改代碼
  if (token) {
    config.headers['Authorization'] = 'Bearer ' + token // 讓請求header攜帶access_token。可根據業務須要修改代碼
  }
  return config
}, error => {
    Toast.message({
      close: false,
      message: '請求異常,請稍後再試~',
      color:'rgba(0,0,0,.55)'
    })
})

// respone攔截器,實現鑑權刷新
service.interceptors.response.use(
  response => response,
  error => {
    const config = error.config // 能夠試着打印config看看具體是些什麼
    // 這裏我對多數的狀態碼進行了一個統一整理。
    if (error.response.status === 400) {
      Toast.message({
        color:'rgba(0,0,0,.55)',
        message: error.response.data.err_msg,
        close: false
      })
    }
    if (error.response.status === 500) {
      Toast.message({
        close: false,
        message: '請求異常,請稍後再試~',
        color:'rgba(0,0,0,.55)'
      })
    }
// 重點代碼:當服務器返回401狀態碼時,使用refresh刷新接口更新已有token,再重複上一個接口請求,若失敗,退出登陸
    if (error.response.status === 401) {
      if (config.url != config.baseURL + '/refresh') { // 判斷上一次請求是不是刷新請求。不判斷的話,容易出現一直刷新的bug
        const retryreq = new Promise((resolve, reject) => { // 必須使用promise,不然不會被返回執行上一布操做
          // 使用refresh接口
          refresh({refresh_token: sessionStorage.getItem('refresh_token')}).then(res => {
            let data = res.data.data
            // 更新token
            sessionStorage.setItem('refresh_token', data.refresh_token) 
            sessionStorage.setItem('access_token', data.access_token)
            config.headers['Authorization'] = 'Bearer ' + sessionStorage.getItem('access_token')
            config.baseURL = ''
            resolve(service(config)) // 必須resolve
          }).catch(error => {
            console.log(error)
          })
        })
        return retryreq;
      } else {
        // 若是刷新失敗從新登陸
        Toast.message({
          close: false,
          message: '登陸失效,請從新登陸',
          color:'rgba(0,0,0,.55)'
        })
        removeToken()
        sessionStorage.clear()
        location.reload()
      }
    }
    return Promise.reject(error);
  }
)
export default service
關於請求接口的封裝

上面的代碼中引入了一個 refresh
import {refresh} from '@/api/user' // 封裝好的refresh(鑑權須要刷新)接口es6

在工做中,與後臺交互必不可少,怎樣使請求方式看着更加簡介好看,須要對請求接口的api進行封裝。
在上面的代碼中,已經實現了對axios網絡請求的封裝了。我通常會在src目錄下新建一個api文件夾,在裏面分別建立請求對應的js文件:
npm

方法一:

上代碼:axios

import request from "@/utils/request"; // 引入已經封裝好的js文件,我這裏叫request,根據本身須要修改。
export function refresh (data) {
    return request({
        url: '/refresh', // 接口名稱
        method: 'post',  // 接口方法
        data: data // 參數
    })
}

使用api

import {refresh} from '@/api/user
refresh(參數).then(res => {
   //  do something
}).catch(err => {
    // do something
})
方法二:

上代碼promise

import request from "@/utils/request"; 

const user = {
  refrsh: function (query) {
    return request({
      url: '/refrsh',
      method: 'get',
      params: query
    })
  },
  ....
}
export default user

使用服務器

import user from '@/api/user
user.refresh(參數).then(res => {
   //  do something
}).catch(err => {
    // do something
})

以上代碼只是es6的兩種導出引入文件的使用,可根據業務的複雜程度選擇合適的代碼風格。注意引入方式{}的區別。axios的使用就是這個樣子的啦~網絡

相關文章
相關標籤/搜索