記一次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; };
-
對請求結果進行解析,當返回數據類型不同時採用不同的解析方式。
//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(); };
-
封裝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); }); }
-
封裝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); };
-
使用
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