vue之a(chǎn)xios篇

axios里面可以設(shè)置攔截器 ,可以在我們正式請(qǐng)求發(fā)送之前做一些事情
攔截器分請(qǐng)求(request)攔截器和響應(yīng)(response)攔截器

最近在項(xiàng)目開發(fā)中,前后端交互時(shí),經(jīng)常會(huì)使用到token

在進(jìn)行敏感操作之前,每個(gè)請(qǐng)求需要攜帶token,但是token 有有效期,token 失效后需要換取新的token并繼續(xù)請(qǐng)求。

需求分析

首次請(qǐng)求后臺(tái)把token返回給前端,前端把這個(gè)token可以保存起來, 然后每次請(qǐng)求后端都需要帶上這個(gè)token 進(jìn)行鑒權(quán)驗(yàn)證
如果我們每次請(qǐng)求都在路徑后面加上http://abc.com/list?token=xxxx 這種形式
如果請(qǐng)求特別多的話 每次都在后面寫上token=xxx這種太麻煩
這時(shí)候就可以用 axios request 攔截器,給每個(gè)請(qǐng)求都加 token,這樣就可以節(jié)省每個(gè)請(qǐng)求再一次次的復(fù)制粘貼代碼。

token 失效問題,當(dāng)我們token 失效,我們服務(wù)端會(huì)返回一個(gè)特定的錯(cuò)誤表示,比如 token invalid,但是我們不能在每個(gè)請(qǐng)求之后去做刷新 token 的操作呀,所以這里我們就用 axios response 攔截器,我們統(tǒng)一處理所有請(qǐng)求成功之后響應(yīng)過來的數(shù)據(jù),然后對(duì)特殊數(shù)據(jù)進(jìn)行處理,其他的正常分發(fā)。

具體實(shí)現(xiàn)

  1. 下載安裝axios:
    npm install axios
  2. 引入(在哪里使用就在哪里引入)
    import axios from 'axios'
  3. 封裝request.js(位置:utils/request.js)代碼如下:
import axios from "axios";
import {Notification, MessageBox, Message} from 'element-ui';
import errorCode from '@/utils/errorCode';

axios.defaults.headers["Content-Type"] = "application/json;charset=utf-8";
// 創(chuàng)建axios實(shí)例 axios.create([config])
const service = axios.create({
  // axios中請(qǐng)求配置有baseURL選項(xiàng),表示請(qǐng)求URL公共部分
  baseURL:
    process.env.NODE_ENV === "production" //正式生產(chǎn)環(huán)境,程序最終發(fā)布后所需要的參數(shù)配置
      ? process.env.VUE_APP_BASE_URI
      : process.env.VUE_APP_BASE_API,
  // 超時(shí)
  timeout: 30000
});
// request攔截器
service.interceptors.request.use(
  config => {
    // 是否需要設(shè)置 token
    config.headers["token"] =sessionStorage.getItem('toKenValue'); // 讓每個(gè)請(qǐng)求攜帶自定義token 請(qǐng)根據(jù)實(shí)際情況自行修改
    return config;
  },
  error => {
    console.log(error);
    Promise.reject(error);
  }
);

// 響應(yīng)攔截器
axios.interceptors.response.use(
  res => {
    // 未設(shè)置狀態(tài)碼則默認(rèn)成功狀態(tài)
    const code = res.data.code || 200;
    // 獲取錯(cuò)誤信息
    const msg = errorCode[code] || res.data.message || errorCode['default'];
    if (code === 403) {
      MessageBox.confirm('登錄狀態(tài)已過期,請(qǐng)重新登錄', '系統(tǒng)提示', {
        confirmButtonText: '重新登錄',
        cancelButtonText: '取消',
        type: 'warning',
      }).then(() => {
        // 跳轉(zhuǎn)登錄頁
        sessionStorage.removeItem('toKenValue');
        router.push(
          '/login',
          () => {},
          e => {}
        );
        return false;
      });
    } else if (code === 500) {
      Message({
        message: msg,
        type: 'error',
      });
      return Promise.reject(new Error(msg));
    } else if (code !== 200) {
      Notification.error({
        title: msg,
      });
      return Promise.reject('error');
    } else {
      return res.data;
    }
  },
  error => {
    console.log('err' + error);
    let {message} = error;
    if (message == 'Network Error') {
      message = '后端接口連接異常';
    } else if (message.includes('timeout')) {
      message = '系統(tǒng)接口請(qǐng)求超時(shí)';
    } else if (message.includes('Request failed with status code')) {
      message = '系統(tǒng)接口' + message.substr(message.length - 3) + '異常';
    }
    Message({
      message: message,
      type: 'error',
      duration: 5 * 1000,
    });
    return Promise.reject(error);
  }
);
export default service;

哪里可以配置axios呢

  • axios全局配置
//如果create()里不添加參數(shù)的話,在創(chuàng)建這個(gè)axios實(shí)例的時(shí)候,使用的就是全局的配置
//axios.defaults.后邊跟的就是axios的那些配置
//一般修改的全局配置,也就下邊這兩個(gè)
axios.defaults.withCredentials = true;
axios.defaults.timeout = 10000;
axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
  • axios實(shí)例配置
//如果設(shè)置了全局的配置,但是又想在創(chuàng)建的實(shí)例里修改
const service = axios.create({
  timeout: 30000
})
  • axios請(qǐng)求配置
//如果設(shè)置了全局的配置,但是又想在創(chuàng)建的實(shí)例里修改
 let instance = axios.create();
    instance.get('/data.json',{
        timeout:5000
    })

-這3種配置方法的優(yōu)先級(jí)是 axios請(qǐng)求配置> axios實(shí)例配置 > axios全局配置

:timeout的作用
:timeout 超時(shí)時(shí)長(zhǎng) 默認(rèn)是1秒,超時(shí)時(shí)長(zhǎng)的意思是,發(fā)起請(qǐng)求的時(shí)候,服務(wù)端長(zhǎng)時(shí)間沒有返回?cái)?shù)據(jù),接口就會(huì)報(bào)超時(shí)401具體的超時(shí)時(shí)長(zhǎng)一般是由后端定義的,比如當(dāng)前端請(qǐng)求了一個(gè)比較大的數(shù)據(jù),后端需要進(jìn)行處理,一旦處理時(shí)間過長(zhǎng),比如超過1秒那么后端可能就直接返回401,告訴前端接口超時(shí)了,這個(gè)時(shí)候其實(shí)前端也需要做響應(yīng)的處理

:axios創(chuàng)建實(shí)例作用是啥,為啥要?jiǎng)?chuàng)建一個(gè)實(shí)例
:可以不創(chuàng)建一個(gè)axios實(shí)例,默認(rèn)會(huì)導(dǎo)出實(shí)例axios,通常你只需使用這個(gè)axios就可以了。
但是有時(shí)候你需要?jiǎng)?chuàng)建多個(gè)實(shí)例,比如你需要訪問多個(gè)服務(wù)地址,而這些服務(wù)請(qǐng)求和響應(yīng)的結(jié)構(gòu)都完全不同,那么你可以通過axios.create創(chuàng)建不同的實(shí)例來處理。
比如axios1是用http狀態(tài)碼確定響應(yīng)是否正常,而axios2是服務(wù)器自己定義的狀態(tài)碼,又或者他們請(qǐng)求頭不同,支持的content-type不同,那么我可以單獨(dú)為axios1和axios2寫攔截器。

:關(guān)于axios的baseURL是使用相對(duì)路徑還是絕對(duì)路徑?
:前后端都部署在同一臺(tái)服務(wù)器可以用相對(duì)路徑, 部署在不同服務(wù)器用絕對(duì)路徑。
一般是寫相對(duì)路徑,這樣部署前端代碼,只要把前端包放在哪個(gè)環(huán)境下,就直接放,不需要前端再重新修改一個(gè)路徑再打包了。

request.js:

 baseURL:
    process.env.NODE_ENV === "production"
      ? process.env.VUE_APP_BASE_URI
      : process.env.VUE_APP_BASE_API,

.env.production:(生產(chǎn)環(huán)境)

VUE_APP_BASE_URI = 'http://xxx.com/massgroup-fz'

.env.development:(開發(fā)環(huán)境--用于本地開發(fā)聯(lián)調(diào))

VUE_APP_BASE_API = '/dev-api'

.env.staging:(測(cè)試環(huán)境)

VUE_APP_BASE_API = '/massgroup'
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容