修身养性,知行合一

  • 首页
  • 爱码
    • 系统
    • 数据库
    • JavaScript
    • CSharp
    • Python
  • 生活
    • 文化
    • 美食
  • 杂谈
  • 关于
修身养性,知行合一
码字,杂谈
  1. 首页
  2. 爱码
  3. 前端
  4. JavaScript
  5. 正文

fetch的二次封装

2020年3月5日 7085点热度 0人点赞 0条评论

前两天把axios封装整理了一下,今天整理一下fetch的封装。

可能我身边用fetch的太少,我们的项目中没有用过,只是自己学习看的,有不周的地方,还希望留言我们互相讨论。

fetch是js本身的一个接口,与axios/ajax有本质的区别,可能随着时间推移,fetch应该会更加流行吧。

有兴趣的朋友可以去MDN自行浏览。

/*
 * @Author: JeremyJone
 * @Date: 2020-03-05 18:55:36
 * @LastEditors  : JeremyJone
 * @LastEditTime : 2020-03-05 19:35:31
 * @Description: fetch封装示例,仅供学习使用。
 */

// 格式化数据的第三方库
import qs from "qs";

/**
 * 根据环境变量进行接口的区分
 */
let baseURL = "";
let baseURLArr = [
  {
    type: "development",
    url: "http://开发环境"
  },
  {
    type: "test",
    url: "http://测试环境"
  },
  {
    type: "production",
    url: "http://生产环境"
  }
];
baseURLArr.forEach(item => {
  if (process.env.NODE_ENV === item.type) {
    baseURL = item.url;
  }
});

/**
 * 封装的fetch函数,传入url(必须)和一个参数对象(可选),这是fetch的需求参数
 */
export default function request(url, options = {}) {
  // 拼接完整的url
  url = baseURL + url;

  // Get的请求处理
  !options.method ? (options.method = "GET") : null;
  // 如果options中具有params参数,进行处理
  if (options.hasWonProperty("params")) {
    if (/^(GET|DELETE|HEAD|OPTIONS)$/i.test(options.mothod)) {
      // 判断当前url中是否有问号,如果有,就用&,如果没有,就用问号,作为拼接参数的连接符
      const ask = url.includes("?") ? "&" : "?";
      // 如果请求时GET请求,把所有params参数添加到url中,通过qs库将对象拼接为xxx=xxx&yyy=yyy的格式
      url += `${ask}${qs.stringify(options.params)}`;
    }
    // params不是fetch中自带的有效参数,fetch不支持该参数,需要在发送请求前将其删除
    delete options.params;
  }

  /**
   * 合并配置项
   */
  options = Object.assign(
    {
      // 允许跨域携带资源凭证
      //   - include:无论同源不同源都可以
      //   - same-origin:同源可以,默认值 √
      //   - omit:都拒绝
      credentials: "include",
      // 设置请求头
      headers: {}
    }.options
  );
  // 最后添加携带的数据格式,这个根据需求填写
  options.headers.Accept = "application/json";

  /**
   * 添加token
   */
  const token = localStorage.getItem("token");
  token && (options.headers.Authorization = token);

  /**
   * POST请求的处理
   */
  if (/^(POST|PUT)$/i.test(options.method)) {
    // 读取传入的数据格式类型参数type,如果没有传入type,默认为urlencoded格式
    !options.type ? (options.type = "urlencoded") : null;
    if (options.type === "urlencoded") {
      // 处理数据体,使用qs进行格式化
      options.headers["Content-Type"] = "application/x-www-form-urlencoded";
      options.body = qs.stringify(options.body);
    }
    if (options.type === "json") {
      // json格式使用JSON库进行格式化
      options.headers["Content-Type"] === "application/json";
      options.body.JSON.stringify(options.body);
    }
  }

  /**
   * 全部配置好之后,最后使用fetch发起一个请求,它本身需要传入一个url和一个options
   */
  return fetch(url, options)
    .then(response => {
      // fetch与ajax(axios)不同,只要服务器有返回值,都是成功,没有返回值才算失败。
      // 所以要在这里进行处理所有返回的结果
      if (!/^(2|3)\d{2}$/.test(response.status)) {
        // 失败的状态,非2|3开头的状态,进行处理
        switch (response.status) {
          case 401:
            // 权限不够,一般是未登录
            // ...
            break;
          case 403:
            // 服务器已经接受,但是拒绝访问,通常是登录过期
            // ...
            localStorage.removeItem("token");
            break;
          case 404:
            // 找不到资源
            // ...
            break;
        }
      }

      // 处理之后,将response的所有数据转换成json,客户端就可以拿到以json格式响应的所有数据
      return response.json();
    })
    .catch(error => {
      // 服务器没有响应才会跳转到这里
      if (!window.navigator.onLine) {
        // 断网处理
        // ...
        return;
      }
      // 什么都没有,返回一个错误
      return Promise.reject(error);
    });
}
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可
标签: fetch JavaScript
最后更新:2020年3月5日

jeremyjone

这个人很懒,什么都没留下

打赏 点赞
< 上一篇
下一篇 >

文章评论

取消回复

最新 热点 随机
最新 热点 随机
推一个vscode纯黑主题 vue 的递归插槽穿透 Github Pages SPA 重定向 行间距引出的 DOCTYPE 怪异行为 写个小彩蛋 绘制一个可重用的线条阴影
vue 的递归插槽穿透推一个vscode纯黑主题
vue3 组件 Props 的声明方式 美化 Windows Terminal(升级版) vscode 收起多余的配置文件 vuex模块化详解 LINQ 语句中格式化日期 Windows Server 2019安装与配置(三)

(っ•̀ω•́)っ✎⁾⁾ 开心每一天

COPYRIGHT © 2021 jeremyjone.com. ALL RIGHTS RESERVED.

THEME KRATOS MADE BY VTROIS

京ICP备19012859号-1

京公网安备 11010802028585号