• 當前位置:首頁 > IT技術 > 移動平臺 > 正文

    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/'; // 生產 : 測試
    
    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靈活配置

    創建三個文件(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
     * 生成基礎axios對象,并對請求和響應做處理
     * 前后端約定接口返回解構規范
     * {
     *    code:0,
     *    data:"成功",
     *    message:""
     * }
     */
    import axios from 'axios'
    import { Message } from 'element-ui'
    
    // 創建一個獨立的axios實例
    const service = axios.create({ 
        // 設置baseUr地址,如果通過proxy跨域可直接填寫base地址
        baseURL: '/api',
        // 定義統一的請求頭部
        headers: {
            post: {
                "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8"
            }
        },
        // 配置請求超時時間
        timeout: 10000, 
        // 如果用的JSONP,可以配置此參數帶上cookie憑證,如果是代理和CORS不用設置
        withCredentials: true
    });
    // 請求攔截
    service.interceptors.request.use(config => {
        // 自定義header,可添加項目token
        config.headers.token = 'token';
        return config;
    });
    // 返回攔截
    service.interceptors.response.use((response)=>{
        // 獲取接口返回結果
        const res = response.data;
        // code為0,直接把結果返回回去,這樣前端代碼就不用在獲取一次data.
        if(res.code === 0){
            return res;
        }else if(res.code === 10000){
            // 10000假設是未登錄狀態碼
            Message.warning(res.message);
            // 也可使用router進行跳轉
            window.location.href = '/#/login';
            return res;
        }else{
            // 錯誤顯示可在service中控制,因為某些場景我們不想要展示錯誤
            // Message.error(res.message);
            return res;
        }
    },()=>{
        Message.error('網絡請求異常,請稍后重試!');
    });
    export default service;
    
    /**
     * request.js
     * 通過promise對axios做二次封裝,針對用戶端參數,做靈活配置
     */
    import { Message,Loading } from 'element-ui';
    import instance from './interceptor'
    
    /**
     * 核心函數,可通過它處理一切請求數據,并做橫向擴展
     * @param {url} 請求地址
     * @param {params} 請求參數
     * @param {options} 請求配置,針對當前本次請求;
     * @param loading 是否顯示loading
     * @param mock 本次是否請求mock而非線上
     * @param error 本次是否顯示錯誤
     */
    function request(url,params,options={loading:true,mock:false,error:true},method){
        let loadingInstance;
        // 請求前loading
        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平臺可對局部接口進行mock設置
            if(options.mock)url='http://www.mock.com/mock/xxxx/api';
            instance({
                url,
                method,
                ...data
            }).then((res)=>{
                // 此處作用很大,可以擴展很多功能。
                // 比如對接多個后臺,數據結構不一致,可做接口適配器
                // 也可對返回日期/金額/數字等統一做集中處理
                if(res.status === 0){
                    resolve(res.data);
                }else{
                    // 通過配置可關閉錯誤提示
                    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
    }
    
    • 導入
    // 導入插件
    import request from './api/request'
    // 在原型上擴展,這樣不用在每個頁面都導入request
    Vue.prototype.request = request;
    
    • 調用
    this.request.get('/login',{userName:'admin',userPwd:'admin'}).then((res={})=>{
            // 此處只接收成功數據,失敗數據不返回
      }).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'
    // 創建axios實例
    const service = axios.create({
      // axios中請求配置有baseURL選項,表示請求URL公共部分
      baseURL: process.env.VUE_APP_SERVER_URL,
      // 超時
      timeout: 100000
    })
    // request攔截器
    service.interceptors.request.use(config => {
      // 是否需要設置 token
      const isToken = (config.headers || {}).isToken === false
      if (getToken() && !isToken) {
        config.headers['Authorization'] = getToken() // 讓每個請求攜帶自定義token 請根據實際情況自行修改
      }
      // get請求映射params參數
      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)
    })
    
    // 響應攔截器
    service.interceptors.response.use(res => {
        // 未設置狀態碼則默認成功狀態
        const code = res.status || 200;
        // 獲取錯誤信息
        const msg = errorCode[code] || errorCode['default']
        if (code === 401) {
          MessageBox.confirm('登錄狀態已過期,您可以繼續留在該頁面,或者重新登錄', '系統提示', {
              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 = "系統接口請求超時";
        }
        else if (message.includes("Request failed with status code")) {
          message = "系統接口" + message.substr(message.length - 3) + "異常";
        }
        Message({
          message: message,
          type: 'error',
          duration: 5 * 1000
        })
        return Promise.reject(error)
      }
    )
    
    export default service
    
    

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

    開通會員,享受整站包年服務
    国产呦精品一区二区三区网站|久久www免费人咸|精品无码人妻一区二区|久99久热只有精品国产15|中文字幕亚洲无线码