在上闲逛,看过太多人都喜欢基于axios进行二次的封装。如前几天在某网站上看到一篇文章,说是用 ts 对 axios 进行了下封装,从点赞量、评论量和访问量上来看,有很多httpwatch人都看过这篇文章了。

真没必要再对 axios 进行过度的封装

我之前也看过 axaxiosios 的源码,也基于 axios 进行过扩展和二次浏览器下载封装。对 axios 的内部原理和使用方式不可谓不熟悉。

虽然很多人在评论里说,收益匪浅啊,写的真棒啊等等,但我通读完整篇文章,得iOS到的https协议结论是:完全没必要

1. 完全没必要

有的开浏览器怎么打开网站发者喜欢基于 axios 再在外层封装一层,但这种方式实现的成本太高。

无论是实现跟 axios 一样的功能,还是外层进行简化,然后再按照 axios 的方式传给 axios,都增加了很多开发的成本。如:

const myAxios = async (config) => {
  /**
   * 中间各种封装,然后最后再使用axios发起请求1
   * */
  try {
    const { status, data } = await axios(config);
    if (status >= 200 && status <= 304) {
      return data;
    }
  } catch (err) {
    console.error(err);
  }
  return null;
};

如有的开发者封装时,喜ios越狱欢把 GET 请求方式的 params 字段和 POST 请求iOS方式的 data 字段合并成一个,觉得可以减浏览器历史记录设置少使用者对字段记忆的成本。然后组件内部,再根据请求方式,决定传给 axios 的 params 字段还是 data 字段。或者有的屏蔽掉对请求的配置,有的屏蔽掉 axios应用商店ios 对外返回的字段。

就像上面的简要封装,连拦截器、取消请求等功能都给屏蔽掉了。但是,又想用,怎么办?那就靠着自己半吊子的知识,自己再封装一个,然后再跟 axios 进行对接,累不累啊。

有的人说他的要求更复杂,不二次额外浏览器哪个好封装一层,都没法用,比如:

  1. 一个 url 同时只有发起一个请求;
  2. 有重试的iOS机制,当不满足要求时,最多可以ios14.4.1更新了什么重试 3 次;
  3. 统一的 loading 机制;
  4. 配置复杂,不同的 URL 有着不同的配置;

其实,上面的这几条需求,通过 axios 的拦axios和ajax区别截器就可以实现了,外面不用再封装一层。

axios 库本身就已经提供了多种的扩展方式,为什么不直接用呢?

真没必要再对 axios 进行过度的封装

1.1 方便扩展的适配器

axios 可以自定义请求适配器 adapter。

很多同学说 fetc浏览器历史上的痕迹在哪里h 已经成为标准了,为什么 axios 内部还不支持。其实相比 XMLHttpRequest ,fetch 还是多少有点欠缺的,如取消ios16请求的 AbortController 在 IE 浏览器中并没有实现,同时也不支持上传进度和下载进度。

因此,在 fetch 还没有对齐 XMLHttpRequest 里的这些功能时,内部还httpclient很难使用 fetch 来实现。

若您真的想用 fetch 来进行请求,完全可以按照文档来扩展您的适配器。如何实现自定义的适配器,您可以参考这篇文章 如何实现 axios 的自定义适配器 adapter。

直接在适配器上进行扩展,而不是基于 axios 再在外层封装一层,原因有几个:

  1. 不改变 axios 的使用方式,无论传参的浏览器网站删除了怎么恢复方式,还是数据返回的格式,都没有任何的变化;
  2. 可以使用浏览器历史上的痕迹在哪里 axios 中提供的能力,如拦截器,转换请求数据和响应数据、支持防御 XSRF 等;

这种httpwatch方式,对其他开发者也很友好,只要知道 axios 怎么用,就知道你封装的这个怎么用。不用增加学习的成本。

真没必要再对 axios 进行过度的封装

1.2 各种形式的配置

axios 在ios系统配置上,可以进行全局的配置和请求的单独配置,同时还有请求拦ios是苹果还是安卓截器和响应拦截器,对某一类的请求进行处理。

若所有请求的 url 的 baseURL 是相同的,那么就可以在全局http 302配置中进行配置;若某几个接口的 baseUrl 跟别的不一样,那么可以单独https协议对其进行配置,或者在请求拦ios系统截器中,直接修改请求HTTPS的 baseUrl。

axios.defaults.timeout = 6000; // 全局配置
/**
 * 拦截器中配置,若url中有`aaa`,则过期时间设置为4000ms
 **/
axios.interceptors.request.use(
  function (config) {
    if (/aaa/.test(config.url)) {
      config.timeout = 4000;
    }
    return config;
  },
  function (error) {
    return Promise.reject(error);
  },
);
axios('https://www.xiabingbao.com', { timeout: 2000 }); // 单独对某个请求进行配置

这些不同的配置方式,我个人觉得已经可以满足绝大部分的需求了。

1.3 本身就支持 typescript

axios 源码虽不是用 typescript 编写的,但官https和http的区别方也是提供了 ts 定义的:index.d.ts。

那些上来就说用 typescript 封装 axios 的,你确定不是在搞笑吗?

而且,做为个人开发者,在开发和使用过程中,肯定会产生纰漏和 bug,比不过经过多人验证过的仓库。

真没必要再对 axios 进行过度的封装

2. 不是不能封https协议http://www.baidu.com

其实也不是不能封装,毕竟 axios 做为一个通用的框架,它不可能适应所有的项目和架ios系统构。ios是苹果还是安卓我不希望的是过度的封装,既没必要,又增加后来者的学习成本。

有的同http代理学在 React/Vue 中封装 axios,倒是可以有封装的意义,比如在 React 中封装一个请求的简单 hook 等。

const useAxios = (config) => {
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  const [result, setResult] = useState(null);
  useEffect(() => {
    setLoading(true);
    axios(config)
      .then(setResult)
      .catch(setError)
      .finally(() => {
        setLoading(false);
      });
  }, []);
  return { loading, error, result };
};

更具体的如何在 React 封装一个请求的 hook,可以参考该链接:使用 react 的 hook 实现一个 useRequest。

有的封装,是为了减少项目整体的改造成本,和其他人学习新用法的成本。比如之前我也基于 axios,在外层封装过https认证一个请求库。当时为了跟之前的请求方式保持一致,就在外层额外封了一层。后来就出现当需要扩展功能时,特别麻烦,还不如从一开始设计时,就仅仅扩展他的适配器,或者https协议几个简单的配置浏览器推荐就行。

在封装的时浏览器哪个好候,首先我们要明http 500白 axios 可以完成什么工作,他实现这些功能都有什么意义,为什么可以传入这些字段,又为什么要返回了那么多字段(我明明只需要接口返回的 data)?

想明白这些问题,就知道我们ios是苹果还是安卓要保留什么,如何进行扩展和封装了。

真没必要再对 axios 进行过度的封装

3. 总结

自己实现出来的东西,大部分都比不上社区里浏览器数据如何恢复经过千锤浏览器历史上的痕迹在哪里百炼验证过的。而且在使用的过程中,还要考虑减少其他人的学习成本。

比如你就不想用 Vue,觉得 Vue 这个框架优点大,然后选择了一个叫mini-vue的框架来开发项目。就社区完善程度来说,这个 mini 版肯定是比不上官方http 302 Vue 的,后来者还得重新学习 mini 版的语法,当遇到问题时,都不知道去问谁,毕竟这个问题,只有 mini 版里才会有,其他人用的少,解答的人也少。

如果您喜欢我的文章,也欢迎关注我的公众号。