全国协议5人面授小班,企业级独立开发考核,转业者的IT软件工程师基地 登录/注册 | 如何报名
当前位置: 前端开发   >  jQuery Ajax、fetch 和 axios
admin · 更新于 2021-08-06

前言

近年来,前端技术呈现一派迅猛发展的态势,随之而来的是,前后端通信方式也发生了翻天覆地的变化,从一开始的重载页面的老旧方式,逐步发展到如今 XMLHttpRequest 和 fetch。相应的,各种各样的 Ajax 类库推陈出新,不断的进步。这个章节,我们打算来聊一聊 jQuery Ajax、fetch和 axios,相信同学们将会有一个更加全面的了解。

1.jQuery Ajax

这个技术在前面章节有独立章节进行讲解。事实上,$.ajax 是基于原生 XMLHttpRequest 进行了封装,并且提供了一套高度统一的设计和编程接口。在我们的代码中,我们一般都这样写:

$.ajax({
    method: 'POST',
    url: url,
    data: data,
    success: function () {},
    error: function () {}});
代码块
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

或者结合 deferred 的写法:

$.ajax({
    url: url,
    method: 'GET',
    data : data}).done(data => {
    // code}).fail(err => {
    // code})
代码块
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

不吹不黑,jQuery 提供的这一套 Ajax 工具方法真的非常优秀,并且经历了这么多年的打磨,其稳定性、成熟度自然不必多言。关于 jQuery 的 Ajax 工具方法的优点,在前面章节已经讲过。至少从使用体验上来讲,简单易用,功能齐全,以至于我身边至今依然有很多开发者在使用这一套工具函数。

然而,随着技术的发展,jQuery 也逐步走向一个衰弱的过程。越来越多的前端开发者开始使用诸如 AngularReact 和 Vue 这样的新型框架。想像一下,如果我们在一个基本用不到 jQuery 的技术中进行前端开发,为了要使用 jQuery 的 Ajax 相关方法而强行引入整个 jQuery,这显然是不现实也不可取的。在更新的技术中,我们将寻求体积更小,更为先进的类库。

2.fetch

fetch 面世以来,一直都被称为是 Ajax 的替代方案。作为一个底层的 API 而言,我们将它和 XMLHttpRequest 来进行比较。

相信使用过 XMLHttpRequst 的同学,在惊叹它赋予的前后端交互方式的同时,也无不会诟病它丑陋的代码组织方式。

举个例子来说明,假设我们要往后端发送一段 GET 请求,使用 XMLHttpRequest 我们会这样做:

var xhr = new XMLHttpRequest();xhr.open('GET', url);xhr.responseType = 'text';xhr.onreadystatechange = function() {
    if (this.readyState == 4) {
        if (this.status === 200 || this.status === 304) {
			// code ...
        }
    }};xhr.onerror = function() {
  console.log("Oops, error");};xhr.send();
代码块
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

这代码的组织简直是丑陋,写起来也非常的麻烦、松散。

而 fetch 在这方面的表现就不一样了。Fetch API 是基于 promise 进行设计的,写法上也更加的方便和简单,更为符合关注点分离的原则,不会将所有的配置和状态混淆在一个对象里。 接下来我们来看看使用 fetch 的写法:

// 写法一:fetch(url)
    .then(response => {
        if (response.ok) {
            return response.json();
        }
    })
    .then(data => {// code...})
    .catch(err => {// code...})
        // 写法二:const fetchSend = async (url) => {
    try {
        const response = await fetch(url);
        if (response.ok) {
            return response.json()
        }
      } catch(e) {
        // code ...
      }}fetchSend(url)
代码块
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

感觉瞬间优雅了许多有木有!使用 promise 写法,我们的整个代码组织变得更加整洁有条理性。而方法二使用 async/await 结合 fetch 的编码形式,让我们能够以同步的方式来书写代码,体验更佳。总结起来:

  • 代码组织简单干净,更具语义性。
  • 可以结合 async/await 书写,体验更佳。

然而,fetch 在其他方面表现并不是都很完美。比如:

  • 原生支持率不佳,兼容性差。
  • 只对网络请求报错,对于诸如 400 和 500 之类的错误,并不会走 reject 分支。
  • 不支持 abort 和 超时控制。
  • 无法检测请求进度。

不得不说, fetch 还需要多多努力呀。

3.axios

接下来讲一下大名鼎鼎的 axios。在 Vue 2.0 之后,著名的 Vue 作者尤雨溪曾推荐过,而我对 axios 的认识也开始于此。

axios 在浏览器端实际上也是基于 XMLHttpRequest 来实现的,并且基于 promise 提供了一套 promise 风格的链式调用 API。在展示代码书写风格之前,我忍不住要说几个 axios 的亮点:

  • 支持 promise API。
  • 支持请求和响应拦截。
  • 提供并发请求接口功能。
  • 轻量高效、简单易用。
  • 客户端支持防止CSRF。
  • 支持 node 端。

可以说,axios 的设计非常的全面和优秀,甚至还支持 node 端,而支持拦截请求和响应、支持并发请求接口更是满足了很多业务场景的需求。接下来看看 axios 一般书写方式:

// 简单的请求axios.get(url, {
    params: params}).then(function (response) {
    // code ...}).catch(function (error) {
    console.log(error);})// 并发请求function axios1() {
    return axios.get(url);}function axios2() {
    return axios.get(url);}axios.all([axios1(), axios2()])
    .then(axios.spread(function (acct, perms) {
    // code ...}));
代码块
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

显而易见,简单、高效,并且 API 体验非常好。事实上,我也更加推荐大家在实际工作中使用 axios 。而关于如何学习 axios ,除了官方文档和各类博客之外,这里我也推荐汉码未来的一门课程 TypeScript 从零重构 Axios,有兴趣一边学习 axios 原理实现,一边造轮子的同学,都可以看看。

4.结尾

一路走来,前端发展的过程中诞生了很多优秀的前后端交互的技术。本章从 jQuery Ajax 、fetch 和 axios 三者展开讨论和比较,尽管 jQuery 对于现在来讲比较老旧了,但这丝毫不妨碍它是一个优秀的类库,它提供的 Ajax 功能也确实是非常好。而 fetch 后来的替代方案,本身的设计也是可圈可点的,只是现在来讲还过于稚嫩,不适用于我们业务中推广使用。相比之下,axios 可算是当打之年,从设计上、从体积上,都很适用于我们现在的各种前端技术体系中,因此,我也推荐同学们可以进一步的学习和使用这个技术。


为什么选择汉码未来