封装fetch请求

您所在的位置:网站首页 封装post接口请求代码 封装fetch请求

封装fetch请求

2023-11-07 05:35| 来源: 网络整理| 查看: 265

背景

在大型项目中,大量的请求,大量重复的代码,让请求封装成为一种必然。

步骤

想要的接口使用方式:

async function getData(params){ return await requestGet(api,params) } getData({id:1}).then(res=>{ // 得到接口数据res即data }) // 或者 let res = await getData({id:1})

requestGet就是要实现的接口封装。

要做的事情 封装fetch方法 在请求之前携带headers、content-type、cookie,get请求将参数带在url后面,post请求将参数携带在body参数 请求过程当中,注意网络错误捕获并抛出 请求正常时,将数据返回给开发者,异常时,统一捕获错误,并抛出 代码实现 import { addDomain } from '@/env'; import onion from './onion.js'; import { message } from 'antd'; /* ** 兼容两种情况 ** 1.帮助用户处理错误信息,用户得到的直接就是data数据 ** 2.用户自己处理错误信息,我们把请求所有res返回 */ function isReturnAllData(obj, res) { const { OPTIONS } = obj; if (OPTIONS && OPTIONS.getAll) { return true; } else { if (res.msg && res.ret !== '0') { message.error(res.msg); } return false; } } export async function request(obj) { let res = await onion(obj); return isReturnAllData(obj, res) ? res : res.data; } export async function requestGetI(url, params, OPTIONS) { url = addDomain(url); return await request({ url, options: { method: 'get', params }, OPTIONS }); } export async function requestPostI(url, params, OPTIONS) { url = addDomain(url); return await request({ url, options: { method: 'post', body: params }, OPTIONS }); } // onion.js import { formatQueryObj } from '@/common/utils'; import { message } from 'antd'; // 用reduce实现promise的串行 export default function onion(obj) { return [frontInterCept, fetcher, endInterCept].reduce((prev, curr) => { return prev .then((res) => curr(res)) .catch((err) => { message.error(err); }); }, Promise.resolve(obj)); } // 前置拦截 function frontInterCept(obj) { return new Promise((resolve, reject) => { let optionFinal = {}; const { url, options } = obj; const { method, params, body } = options; let headers = {}; if (body) { if (body instanceof window.FormData) { /* 单独处理请求参数中存在二进制文件的情况 ** 此时不需要加content-type ** 浏览器发现是二进制文件,会自动加content-type和boundary ** 手动加content-type的话 boundary中的内容会丢失 */ } else { // 普通post请求 headers = { 'content-type': 'application/json; ' }; } } else { // get请求 headers = { 'content-type': 'application/x-www-form-urlencoded; charset=utf-8' }; } optionFinal = method === 'post' ? { headers, method, body: JSON.stringify(body) } : { method, params }; // 允许跨域携带cookie optionFinal.credentials = 'include'; // 允许跨域请求 optionFinal.mode = 'cors'; const tmpQuery = formatQueryObj(params); let urlI = tmpQuery ? url + (url.indexOf('?') !== -1 ? '&' : '?' + tmpQuery) : url; return resolve({ url: urlI, optionFinal }); }); } // 后置拦截 function endInterCept(obj = {}) { const { ret, data } = obj; return new Promise((resolve, reject) => { switch (ret) { case '3': { // 跳转登录页面 return reject('未登录'); } default: { /* ** 单独处理登录,未登录直接跳转 ** 其他错误,将接口所有数据返回,在request那边统一处理 */ return resolve(obj); } } }); } async function fetcher(obj = {}) { return new Promise((resolve, reject) => { const { url, optionFinal } = obj; window .fetch(url, optionFinal) .then((res) => { if (res.status !== 200) { return reject('网络错误,请稍后重试~'); } else { // fetch返回的是一个流对象 res .json() .then((res) => { console.log('res', res); return resolve(res); }) .catch((err) => { return reject('网络错误,请稍后重试~'); }); } }) .catch((err) => { return reject('网络错误,请稍后重试~'); }); }); }

效果:

兼容处理开发者是否需要自己处理错误信息的情况,默认帮他处理

关于请求content-type看这里



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3