當(dāng)前位置:首頁 > IT技術(shù) > 移動平臺 > 正文

axios封裝
2022-02-14 10:44:27

基本

import axios from 'axios'

const baseURL = process.env.NODE_ENV === 'production' ? 'https://api.995120.cn/' : 'http://api-test.995120.cn/'; // 生產(chǎn) : 測試

const instance = axios.create({
  baseURL: baseURL,
  timeout: 10000,
});

export const get = (url, params = {}) => {
  return new Promise((resolve, reject) => {
    instance.get(url, { params }).then((response) => {
      resolve(response.data)
    }, err => {
      reject(err)
    })
  })
}

export const post = (url, data = {}) => {
  return new Promise((resolve, reject) => {
    instance.post(url, data, {
      headers: {
        'Content-Type': 'application/json'
      }
    }).then((response) => {
      resolve(response.data)
    }, err => {
      reject(err)
    })
  })
}

export const patch = (url, data = {}) => {
  return new Promise((resolve, reject) => {
    instance.patch(url, data, {
      headers: {
        'Content-Type': 'application/json'
      }
    }).then(response => {
        resolve(response.data)
      }).catch(err => {
      reject(err)
    })
  })
}

mock靈活配置

創(chuàng)建三個文件(index.js/ interceptor.js/ request.js)
參考自 https://mp.weixin.qq.com/s/A__ereOEdsDri6bgp-0w9g

/**
 * index.js
 * api地址管理
 */
export default {
    login:'/user/login',
    getInfo:'/user/getInfo'
}
/**
 * interceptor.js
 * 生成基礎(chǔ)axios對象,并對請求和響應(yīng)做處理
 * 前后端約定接口返回解構(gòu)規(guī)范
 * {
 *    code:0,
 *    data:"成功",
 *    message:""
 * }
 */
import axios from 'axios'
import { Message } from 'element-ui'

// 創(chuàng)建一個獨(dú)立的axios實(shí)例
const service = axios.create({ 
    // 設(shè)置baseUr地址,如果通過proxy跨域可直接填寫base地址
    baseURL: '/api',
    // 定義統(tǒng)一的請求頭部
    headers: {
        post: {
            "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8"
        }
    },
    // 配置請求超時時間
    timeout: 10000, 
    // 如果用的JSONP,可以配置此參數(shù)帶上cookie憑證,如果是代理和CORS不用設(shè)置
    withCredentials: true
});
// 請求攔截
service.interceptors.request.use(config => {
    // 自定義header,可添加項(xiàng)目token
    config.headers.token = 'token';
    return config;
});
// 返回?cái)r截
service.interceptors.response.use((response)=>{
    // 獲取接口返回結(jié)果
    const res = response.data;
    // code為0,直接把結(jié)果返回回去,這樣前端代碼就不用在獲取一次data.
    if(res.code === 0){
        return res;
    }else if(res.code === 10000){
        // 10000假設(shè)是未登錄狀態(tài)碼
        Message.warning(res.message);
        // 也可使用router進(jìn)行跳轉(zhuǎn)
        window.location.href = '/#/login';
        return res;
    }else{
        // 錯誤顯示可在service中控制,因?yàn)槟承﹫鼍拔覀儾幌胍故惧e誤
        // Message.error(res.message);
        return res;
    }
},()=>{
    Message.error('網(wǎng)絡(luò)請求異常,請稍后重試!');
});
export default service;
/**
 * request.js
 * 通過promise對axios做二次封裝,針對用戶端參數(shù),做靈活配置
 */
import { Message,Loading } from 'element-ui';
import instance from './interceptor'

/**
 * 核心函數(shù),可通過它處理一切請求數(shù)據(jù),并做橫向擴(kuò)展
 * @param {url} 請求地址
 * @param {params} 請求參數(shù)
 * @param {options} 請求配置,針對當(dāng)前本次請求;
 * @param loading 是否顯示loading
 * @param mock 本次是否請求mock而非線上
 * @param error 本次是否顯示錯誤
 */
function request(url,params,options={loading:true,mock:false,error:true},method){
    let loadingInstance;
    // 請求前l(fā)oading
    if(options.loading)loadingInstance=Loading.service();
    return new Promise((resolve,reject)=>{
        let data = {}
        // get請求使用params字段
        if(method =='get')data = {params}
        // post請求使用data字段
        if(method =='post')data = {data:params}
        // 通過mock平臺可對局部接口進(jìn)行mock設(shè)置
        if(options.mock)url='http://www.mock.com/mock/xxxx/api';
        instance({
            url,
            method,
            ...data
        }).then((res)=>{
            // 此處作用很大,可以擴(kuò)展很多功能。
            // 比如對接多個后臺,數(shù)據(jù)結(jié)構(gòu)不一致,可做接口適配器
            // 也可對返回日期/金額/數(shù)字等統(tǒng)一做集中處理
            if(res.status === 0){
                resolve(res.data);
            }else{
                // 通過配置可關(guān)閉錯誤提示
                if(options.error)Message.error(res.message);
                reject(res);
            }
        }).catch((error)=>{
            Message.error(error.message)
        }).finally(()=>{
            loadingInstance.close();
        })
    })
}
// 封裝GET請求
function get(url,params,options){
    return request(url,params,options,'get')
}
// 封裝POST請求
function post(url,params,options){
    return request(url,params,options,'post')
}
export default {
    get,post
}
  • 導(dǎo)入
// 導(dǎo)入插件
import request from './api/request'
// 在原型上擴(kuò)展,這樣不用在每個頁面都導(dǎo)入request
Vue.prototype.request = request;
  • 調(diào)用
this.request.get('/login',{userName:'admin',userPwd:'admin'}).then((res={})=>{
        // 此處只接收成功數(shù)據(jù),失敗數(shù)據(jù)不返回
  }).catch(()=>{
      // catch 可以不要,如果想要捕獲異常,就加上去
  })

若依

import axios from 'axios'
import { Notification, MessageBox, Message } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'
import errorCode from '@/utils/errorCode'

axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 創(chuàng)建axios實(shí)例
const service = axios.create({
  // axios中請求配置有baseURL選項(xiàng),表示請求URL公共部分
  baseURL: process.env.VUE_APP_SERVER_URL,
  // 超時
  timeout: 100000
})
// request攔截器
service.interceptors.request.use(config => {
  // 是否需要設(shè)置 token
  const isToken = (config.headers || {}).isToken === false
  if (getToken() && !isToken) {
    config.headers['Authorization'] = getToken() // 讓每個請求攜帶自定義token 請根據(jù)實(shí)際情況自行修改
  }
  // get請求映射params參數(shù)
  if (config.method === 'get' && config.params) {
    let url = config.url + '?';
    for (const propName of Object.keys(config.params)) {
      const value = config.params[propName];
      var part = encodeURIComponent(propName) + "=";
      if (value !== null && typeof(value) !== "undefined") {
        if (typeof value === 'object') {
          for (const key of Object.keys(value)) {
            let params = propName + '[' + key + ']';
            var subPart = encodeURIComponent(params) + "=";
            url += subPart + encodeURIComponent(value[key]) + "&";
          }
        } else {
          url += part + encodeURIComponent(value) + "&";
        }
      }
    }
    url = url.slice(0, -1);
    config.params = {};
    config.url = url;
  }
  return config
}, error => {
    console.log(error)
    Promise.reject(error)
})

// 響應(yīng)攔截器
service.interceptors.response.use(res => {
    // 未設(shè)置狀態(tài)碼則默認(rèn)成功狀態(tài)
    const code = res.status || 200;
    // 獲取錯誤信息
    const msg = errorCode[code] || errorCode['default']
    if (code === 401) {
      MessageBox.confirm('登錄狀態(tài)已過期,您可以繼續(xù)留在該頁面,或者重新登錄', '系統(tǒng)提示', {
          confirmButtonText: '重新登錄',
          cancelButtonText: '取消',
          type: 'warning'
        }
      ).then(() => {
        store.dispatch('LogOut').then(() => {
          location.href = process.env.VUE_APP_BASE_API + '/index';
        })
      }).catch(() => {});
    } 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 {
      if(null != res.data && null != res.data.success) {
        if(!res.data.success) {
          Message({
            message: res.data.msg,
            type: 'error'
          })
          return Promise.reject(new Error(res.data.msg))
        }
        
        return res.data
      }
    }
  },
  error => {
    console.log('err' + error)
    let { message } = error;
    if (message == "Network Error") {
      message = "后端接口連接異常";
    }
    else if (message.includes("timeout")) {
      message = "系統(tǒng)接口請求超時";
    }
    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

本文摘自 :https://www.cnblogs.com/

開通會員,享受整站包年服務(wù)立即開通 >