记一次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