【重點突破】—— umi-request 基於fetch的網絡請求庫(轉)


前言:umi-request是react項目初始化時,封裝請求通用配置,很好用的基於fetch的請求庫, 結合和優化了fetch與axios的優點。


 

背景

在做中台業務應用開發的過程中,我們發現在請求鏈路上存在以下問題:

  1. 請求庫各式各樣,沒有統一。 每次新起應用都需要重復實現一套請求層邏輯,切換應用時需要重新學習請求庫 API。
  2. 各應用接口設計不一致、混亂。 前后端同學每次需重新設計接口格式,前端同學在切換應用時需重新了解接口格式才能做業務開發。
  3. 接口文檔維護各式各樣。 有的在語雀(雲端知識庫)上,有的在 RAP (開源接口管理工具)上,有的靠閱讀源碼才能知道,無論是維護、mock 數據還是溝通都很浪費人力。

針對以上問題,我們提出了請求層治理,希望能通過統一請求庫、規范請求接口設計規范、統一接口文檔這三步,對請求鏈路的前中后三個階段進行提效和規范, 從而減少開發者在接口設計、文檔維護、請求層邏輯開發上花費的溝通和人力成本。其中,統一請求庫作為底層技術支持,需要提前打好基地,為上層提供穩定、完善的功能支持,基於此,umi-request 應運而生。

umi-request

umi-request 是基於 fetch 封裝的開源 http 請求庫,旨在為開發者提供一個統一的 API 調用方式,同時簡化使用方式,提供了請求層常用的功能:

  • URL 參數自動序列化
  • POST 數據提交方式簡化
  • Response 返回處理簡化
  • 請求超時處理
  • 請求緩存支持
  • GBK 編碼處理
  • 統一的錯誤處理方式
  • 請求取消支持
  • Node 環境 http 請求
  • 攔截器機制
  • 洋蔥中間件機制

與 fetch、axios 的異同?

umi-request 底層拋棄了設計粗糙、不符合關注分離的 XMLHttpRequest,選擇了更加語義化、基於標准 Promise 實現的 fetch(更多細節詳見);同時同構更方便,使用 isomorphic-fetch(目前已內置);而基於各業務應用場景提取常見的請求能力並支持快速配置如 post 簡化、前后綴、錯誤檢查等。

 

上手便捷

安裝

npm install --save umi-request

執行 GET 請求 

import request from "umi-request";
request
  .get("/api/v1/xxx?id=1")
  .then(function(response) {
    console.log(response);
  })
  .catch(function(error) {
    console.log(error);
  });
// 也可將 URL 的參數放到 options.params 里
request
  .get("/api/v1/xxx", {
    params: {
      id: 1
    }
  })
  .then(function(response) {
    console.log(response);
  })
  .catch(function(error) {
    console.log(error);
  });

執行 POST 請求

import request from "umi-request";
request
  .post("/api/v1/user", {
    data: {
      name: "Mike"
    }
  })
  .then(function(response) {
    console.log(response);
  })
  .catch(function(error) {
    console.log(error);
  });

實例化通用配置

請求一般都有一些通用的配置,我們不想在每個請求里去逐個添加,例如通用的前綴、后綴、頭部信息、異常處理等等,那么可以通過 extend 來新建一個 umi-request 實例,從而減少重復的代碼量:

import { extend } from "umi-request";

const request = extend({
  prefix: "/api/v1",
  suffix: ".json",
  timeout: 1000,
  headers: {
    "Content-Type": "multipart/form-data"
  },
  params: {
    token: "xxx" // 所有請求默認帶上 token 參數
  },
  errorHandler: function(error) {
    /* 異常處理 */
  }
});

request
  .get("/user")
  .then(function(response) {
    console.log(response);
  })
  .catch(function(error) {
    console.log(error);
  });

內置常見請求能力

fetch 本身並不提供請求超時、緩存、取消等能力,而在業務開發中卻常常需要,因此 umi-request 對常見的請求能力進行封裝內置,減少重復開發:

{
  // 'params' 是即將於請求一起發送的 URL 參數,參數會自動 encode 后添加到 URL 中
  // 類型需為 Object 對象或者 URLSearchParams 對象
  params: { id: 1 },

  // 'paramsSerializer' 開發者可通過該函數對 params 做序列化(注意:此時傳入的 params 為合並了 extends 中 params 參數的對象,如果傳入的是 URLSearchParams 對象會轉化為 Object 對象
  paramsSerializer: function (params) {
    return Qs.stringify(params, { arrayFormat: 'brackets' })
  },

  // 'data' 作為請求主體被發送的數據
  // 適用於這些請求方法 'PUT', 'POST', 和 'PATCH'
  // 必須是以下類型之一:
  // - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
  // - 瀏覽器專屬:FormData, File, Blob
  // - Node 專屬: Stream
  data: { name: 'Mike' },

  // 'headers' 請求頭
  headers: { 'Content-Type': 'multipart/form-data' },

  // 'timeout' 指定請求超時的毫秒數(0 表示無超時時間)
  // 如果請求超過了 'timeout' 時間,請求將被中斷並拋出請求異常
  timeout: 1000,

  // 'prefix' 前綴,統一設置 url 前綴
  // ( e.g. request('/user/save', { prefix: '/api/v1' }) => request('/api/v1/user/save') )
  prefix: '',

  // 'suffix' 后綴,統一設置 url 后綴
  // ( e.g. request('/api/v1/user/save', { suffix: '.json'}) => request('/api/v1/user/save.json') )
  suffix: '',

  // 'credentials' 發送帶憑據的請求
  // 為了讓瀏覽器發送包含憑據的請求(即使是跨域源),需要設置 credentials: 'include'
  // 如果只想在請求URL與調用腳本位於同一起源處時發送憑據,請添加credentials: 'same-origin'
  // 要改為確保瀏覽器不在請求中包含憑據,請使用credentials: 'omit'
  credentials: 'same-origin', // default

  // 'useCache' 是否使用緩存,當值為 true 時,GET 請求在 ttl 毫秒內將被緩存,緩存策略唯一 key 為 url + params 組合
  useCache: false, // default

  // 'ttl' 緩存時長(毫秒), 0 為不過期
  ttl: 60000,

  // 'maxCache' 最大緩存數, 0 為無限制
  maxCache: 0,

  // 'charset' 當服務端返回的數據編碼類型為 gbk 時可使用該參數,umi-request 會按 gbk 編碼做解析,避免得到亂碼, 默認為 utf8
  // 當 parseResponse 值為 false 時該參數無效
  charset: 'gbk',

  // 'responseType': 如何解析返回的數據,當 parseResponse 值為 false 時該參數無效
  // 默認為 'json', 對返回結果進行 Response.text().then( d => JSON.parse(d) ) 解析
  // 其他(text, blob, arrayBuffer, formData), 做 Response[responseType]() 解析
  responseType: 'json', // default

  // 'errorHandler' 統一的異常處理,供開發者對請求發生的異常做統一處理,詳細使用請參考下方的錯誤處理文檔
  errorHandler: function(error) { /* 異常處理 */ },
}

總結

隨着 umi-request 能力的完善,已經能夠支持各個場景、端應用的請求,前端開發只需要掌握一套 API 調用就能實現多端開發,再也不用關注底層協議實現,把更多的精力放在前端開發上。而基於此,umi-request 能在底層做更多的事情,如 mock 數據、自動識別請求類型、接口異常監控上報、接口規范校驗等等,最終實現請求治理的目標。umi-request 還有很多能力沒有在文中提及,如有興趣歡迎查看詳細文檔,如果你有好的建議和需求,也歡迎提 issue


注:博客轉載自數據體驗技術知乎文章


免責聲明!

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



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