umi-request Ant Pro 的請求庫


umi-request

umi-request 是基於 fetch 的封裝,兼具 fetch 和 axios 的特點。旨在為開發者提供便捷統一的請求方式。Ant Pro 中對 其進行了初步的封裝。比如:統一的錯誤處理方式。

但是,在實際中我們可能會遇見各種各樣的情況,需要按照自己的需求對其進行封裝。那就首先從 Ant Pro 的統一的異常處理程序開始吧。
首先,引入umi-request的擴展到項目中。

import { extend } from 'umi-request';

其次,根據自己的項目實際情況定義錯誤碼和其對應的提示語。

const codeMessage = {
  200: '服務器成功返回請求的數據。',
  201: '新建或修改數據成功。',
  202: '一個請求已經進入后台排隊(異步任務)。',
  204: '刪除數據成功。',
  400: '發出的請求有錯誤,服務器沒有進行新建或修改數據的操作。',
  401: '用戶沒有權限(令牌、用戶名、密碼錯誤)。',
  403: '用戶得到授權,但是訪問是被禁止的。',
  404: '發出的請求針對的是不存在的記錄,服務器沒有進行操作。',
  406: '請求的格式不可得。',
  410: '請求的資源被永久刪除,且不會再得到的。',
  422: '當創建一個對象時,發生一個驗證錯誤。',
  500: '服務器發生錯誤,請檢查服務器。',
  502: '網關錯誤。',
  503: '服務不可用,服務器暫時過載或維護。',
  504: '網關超時。',
};

然后,寫異常處理函數

/**
 * 異常處理程序
 */
const errorHandler = (error: { response: Response }): Response => {
  const { response } = error;
  if (response && response.status) {
    const errorText = codeMessage[response.status] || response.statusText;
    const { status, url } = response;

    notification.error({
      message: `請求錯誤 ${status}: ${url}`,
      description: errorText,
    });
  } else if (!response) {
    notification.error({
      description: '您的網絡發生異常,無法連接服務器',
      message: '網絡異常',
    });
  }
  return response;
};

/**
 * 配置request請求時的默認參數
 */
const request = extend({
  errorHandler, // 默認錯誤處理
  credentials: 'include', // 默認請求是否帶上cookie
  // timeout: 60000, // 請求超時
});

首先第一個需求:對請求結果異常的統一處理。比如:token 失效時,應該統一彈框提示,並且跳回到登錄頁。非成功的統一提示。直接拿到后端返回的數據而去掉外層的包裝。

request.interceptors.response.use(async (response) => {
  const data = await response.clone().json();
  // const currentInterface = getPureInterface(response.url); // 這個方法是為了得到純接口,然后可以適時的選擇跳過,或者做別的操作
  // token 失效
  if(data.code === 1014) {
    window.location.href = `${window.location.origin}/user/login`;
  }
  // 統一報錯信息。需特殊跳過的接口可以在這里跳過
  if(data.code === 1009) {
    // ant 引入的組件
    notification.error({
      message: '請求錯誤',
      description: data.message,
    })
  }
  return response;
})

比如后端接口不同類型需要的參數格式不同。

// get 請求,參數拼接在 url 后面。並且需要在 headers 里面添加參數 token
const requestGet = (url: string, data?: object) => {
  return request.get(`${url}?${qs.stringify({ ...data, t: Date.now() })}`, {
    headers: {
      tokenId: getCookie("token"),
    }
  })
}

// post 請求,form 格式,每個請求都需要包含 token,accout 參數
const requestPost = (url: string, data?: object) => {
  return request.post(url, {
    method: 'POST',
    data: {
      ...data,
      tokenId: getCookie("token"),
      account: getCookie("account"),
    },
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
      tokenId: getCookie("token"),
    }
  })
}

// post 請求,要求的入參卻是 json 格式
const requestPostJson = (url: string, data?: object) => {
  return request.post(url, {
    method: 'POST',
    data,
    headers: {
      'Content-Type': 'application/json',
      tokenId: getCookie("token"),
    },
  })
}
// 這是全局的攔截,還可以寫局部的攔截器

封裝完成之后,最后暴露出來即可使用

export default {
  get: requestGet,
  post: requestPost,
  json: requestPostJson
};

比如請求前的攔截

/**
 * 請求前攔截。比如添加數據或者,修改url
 */
request.interceptors.request.use( (url, options) => {
  // console.log('url=',url)
  // console.log('options', options)
  /**
   * 這里的添加會在上面各自的請求之后執行,比如url 的拼接
   * 這里可以根據 options 的參數決定要不要修改或者拼接不同的前后綴
   * options 包含 credentials、errorHandler、headers、method、params、
   */
  return {
    url: `xingquan${url}&author=guozheng`,
    options: {...options, interceptors: true}
  }
})

還有好多方便的用法,文檔很詳細,使用到再補充。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM