記一次fetch簡單封裝

記一次fetch簡單封裝

剛進公司沒多久,師父分配了一個簡單任務,是做一個產品的官網,以靜態頁面爲主,所有涉及到的接口大概只有5、6個。開始做之前還是考慮到了設計模式、代碼風格啥的,結果開始寫之後害怕在上線之前不能搞定,所以就想着先做一個出來。當然也可能是我太菜,最後終於是做出來上線了。但是有一天師父在審我代碼的時候說我發請求fetch沒有封裝,以後很不好維護,讓我有時間重構一下。這算是給我佈置家庭作業了吧……

網上封裝fetch代碼一搜一大把,我主要是參考的我師父以前的代碼,話不多說看代碼吧!

1. 首先是封裝fetch請求處理:

//api/request.js
//檢查請求返回狀態碼並進行處理
const codeMessage = {
  200: "服務器成功返回請求的數據。",
  201: "新建或修改數據成功。",
  202: "一個請求已經進入後臺排隊(異步任務)。",
  204: "刪除數據成功。",
  400: "發出的請求有錯誤,服務器沒有進行新建或修改數據的操作。",
  401: "用戶沒有權限(令牌、用戶名、密碼錯誤)。",
  403: "用戶得到授權,但是訪問是被禁止的。",
  404: "發出的請求針對的是不存在的記錄,服務器沒有進行操作。",
  406: "請求的格式不可得。",
  410: "請求的資源被永久刪除,且不會再得到的。",
  422: "當創建一個對象時,發生一個驗證錯誤。",
  500: "服務器發生錯誤,請檢查服務器。",
  502: "網關錯誤。",
  503: "服務不可用,服務器暫時過載或維護。",
  504: "網關超時。"
};
const checkStatus = response => {
  //如果狀態碼大於等於200或者小於300,則證明響應沒有問題,可以直接返回響應數據。
  if (response.status >= 200 && response.status < 300) {
    return response;
  }
  //errortext:錯誤信息,如果狀態碼不對,則根據狀態碼打印相應的錯誤信息並拋出
  const errortext = codeMessage[response.status] || response.statusText;
  console.error(`請求錯誤 ${response.status}: ${response.url}`);
  const error = new Error(errortext);
  error.name = response.status;
  error.response = response;
  throw error;
};
  1. 對請求結果進行解析,當返回數據類型不同時採用不同的解析方式。

    //api/request.js
    //解析返回的結果
    const parseResult = response => {
      const contentType = response.headers.get("Content-Type");
      if (contentType != null) {
        if (contentType.indexOf("text") > -1) {
          if (contentType.indexOf("text/html") > -1) {
            return response.json();
          } else {
            return response.test();
          }
        }
        if (contentType.indexOf("form") > -1) {
          return response.formData();
        }
        if (contentType.indexOf("video") > -1) {
          return response.blob();
        }
        if (contentType.indexOf("json") > -1) {
          return response.json();
        }
      }
      return response.json();
    };
  1. 封裝fetch請求

//api/request.js
export default function request(url, option) {
  const defaultOptions = {
    credentials: "include"
  };
  const newOptions = { ...defaultOptions, ...option };
  newOptions.headers = {
    Accept: "application/json",
    ...newOptions.headers
  };
  if (
    newOptions.method === "POST" ||
    newOptions.method === "PUT" ||
    newOptions.method === "DELETE"
  ) {
    if (newOptions.dataType === "json") {
      newOptions.headers["Content-Type"] = "application/json; charset=utf-8";
      newOptions.body = JSON.stringify(newOptions.body);
    } else if (newOptions.dataType === "formEncoded") {
      newOptions.headers["Content-Type"] = "application/x-www-form-urlencoded";
      newOptions.body = qs.stringify(newOptions.body);
    } else {
      newOptions.body = qs.stringify(newOptions.body);
    }
  }
  return fetch(url, newOptions)
    .then(checkStatus)
    .then(response => {
      console.log("---content-type---", response.headers.get("content-type"));
      console.log("---response.status---", response.status);
      if (
        newOptions.method === "DELETE" ||
        response.status === 204 ||
        newOptions.responseType === "text"
      ) {
        return response.text();
      }
      return parseResult(response);
    })
    .catch(e => {
      console.log("請求出錯:", e);
    });
}
  1. 封裝post請求與get請求。

//api/require.js
//post請求
export const postRequest = (url, data = {}) => {
  return request(url, {
    method: "POST",
    dataType: "json",
    mode: "cors",
    body: {
      ...data
    }
  });
};
//get請求
export const getRequest = url => {
  return request(url);
};
  1. 使用

import {postRequest} from 'api/require';
postRequest("http://www,abc.com").then(res => {
    //打印返回數據
    console.log(res)
})

好啦,fetch封裝就到此結束啦~當然我這個只是簡單的小白版本,有問題還請大家指出!

參考:

https://segmentfault.com/a/1190000014733098

完整代碼:

https://github.com/CassielLee/tool-library-js-cl/blob/master/src/api/request.js

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章