fetch API 简单封装

简单封装一下fetch

fetch发起请求的方式

fetch("./01-data.json")
  // 这里的 res拿到的结果是一个流 需要转为 我们需要的格式 json,text,formData等
  // 这几个转换格式的方法 返回值都是 promise实例
  .then(res => res.json())
  .then(res => {
    console.log(res)
  })

是否是普通对象 方法

/**
 * 是否是普通对象 (Object的直接实例)
 * @param {*} obj 
 * @returns 
 */
const isPlainObject = (obj) => {
  let proto, Ctor;
  if (!obj ||
    Object.prototype.toString.call(obj) !== "[object Object]")
    return false;
  proto = Object.getPrototypeOf(obj);
  if (!proto) return true;
  Ctor = proto.hasOwnProperty("constructor") && proto.constructor;
  return typeof Ctor === "function" && Ctor === Object;
}

初始化请求配置参数

// baseURL
let baseURL = "";
// 初始化默认配置
let initialConfig = {
  method: "GET",
  params: null,// get系列请求使用
  body: null,// post系列请求使用 get系列请求不可传body,报错
  headers: {
    "content-type": "application/json"
  }, // 请求头信息
  catch: "no-cache",// 请求不缓存
  credentials: "include", // 跨域携带信息 cookie等
  responseType: "json", // 响应的数据格式
};

根据环境变量设置baseurl

// 根据环境变量 设置 baseURL
// let process;
let env = process?.env?.NODE_ENV || "development";
switch (env) {
  case "development":
    baseURL = "http://localhost:5500";
    break;
  case "production":
    baseURL = "http://localhost:5500"
    break;
  default:
    baseURL = "http://localhost:5500";
    break;
}

封装fetch

const request = function request(url, config) {
  // init params
  if (typeof url !== "string")
    throw new TypeError("url must be required and of string type!");
  // 不是纯对象
  if (!isPlainObject(config)) config = {};
  // 合并配置项(这里应该是深合并,不要使用assign方法)
  config = Object.assign({}, initialConfig, config);
  // handle url
  if (/^http(s?):\/\//i.test(url)) url = baseURL + url;
  let { method, params, body, headers, cache, credentials, responseType } = config;
  // handle params 
  if (params != null) {
    if (isPlainObject(params)) {
      // 转为 name=zs&age=12 这种字符串拼接上去(使用qs库最好)
      let p = "";
      for (const key in params) {
        p += (key + "=" + params[key] + "&");
      }
      params = p.slice(0, -1);
    }
    url += `${url.includes("?") ? "&" : "?"}${params}`;
  }
  // handle body
  if (isPlainObject(body)) {
    body = JSON.stringify(body);
  } else if (typeof body === "string") {
    try {
      JSON.parse(body);
      // 是json字符串 默认就是json来处理的
    } catch (error) {
      // 不是JSON字符串
      // 设置请求头
      headers["content-type"] = "application/x-www-form-urlencoded";
    }
  }
  // common info
  // 类似请求拦截器 比如请求前携带token
  let token = "token";
  if (token) {
    headers["Authorization"] = `Bearer ${token}`;
  }
  // 配置config
  config = {
    method: method.toUpperCase(),
    headers,
    credentials,
    cache,
  }
  if (/^POST|PUT|PATCH$/.test(method) && body != null) config.body = body;
  return fetch(url, config).then(response => {
    let { status, statusText } = response;
    // 只有状态码是以 2 或者 3 开始 才表示请求成功
    if (status >= 200 && status < 400) {
      let result;
      switch (responseType.toUpperCase()) {
        case "JSON":
          result = response.json();
          break;
        case "TEXT":
          result = response.text();
          break;
        case "BLOB":
          result = response.blob();
          break;
        case "ARRAYBUFFER":
          result = response.arrayBuffer();
          break;
        default: // 都不匹配 转json
          result = response.json();
          break;
      }
      return result;
    }
    // 请求失败
    return Promise.reject({
      code: "STATUS ERROR",
      status,
      statusText
    });
  }).catch(reason => {
    // 失败情况
    // @1. 状态码错误
    if (reason && reason.code === "STATUS ERROR") {
      switch (reason.status) {
        case 400:
          break;
        case 401:
          break;
        case 402:
          break;
        case 403:
          break;
        case 500:
          break;
        default:
          break;
      }
    }
    // @2. 网络中断 
    else if (!navigator.onLine) { }
    // @3 其他错误 如请求被终止 取消等
    else { }
    return Promise.reject(reason);
  });
};

使用封装的request方法

request("/01-data.json", {
  responseType: "text"
  , params: {
    name: "zs"
  }
})
  .then(res => {
    console.log(res)
  }).catch(reason => {
    console.log(reason)
  })
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尤雨东

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值