ajax、axios、fetch 对比

前言

今天在看到一个比较好的插件,写一个示例时,由于需要请求在线数据,官方给的是用 $.get(),就为了一个示例使用 JQuery 没必要。

又找了找,发现有用 fecth 的,挺方便,这里就做一个对比。

一、ajax

传统 Ajax 指的是 XMLHttpRequest(XHR), 最早出现的发送后端请求技术,隶属于原始js中,核心使用XMLHttpRequest对象,多个请求之间如果有先后关系的话,就会出现回调地狱

这里说的 ajax 是 JQuery 里面封装的。

JQuery ajax 是对原生XHR的封装,除此以外还增添了对JSONP的支持。经过多年的更新维护,真的已经是非常的方便了,优点无需多言;如果是硬要举出几个缺点,那可能只有:

1.本身是针对MVC的编程,不符合现在前端MVVM的浪潮

2.基于原生的XHR开发,XHR本身的架构不清晰。

3.JQuery整个项目太大,单纯使用ajax却要引入整个JQuery非常的不合理(采取个性化打包的方案又不能享受CDN服务)

4.不符合关注分离(Separation of Concerns)的原则

5.配置和调用方式非常混乱,而且基于事件的异步模型不友好。

示例代码:

$.ajax({
   type: 'POST',
   url: url,
   data: data,
   dataType: dataType,
   success: function () {},
   error: function () {}
});

二、axios

Vue2.0之后,尤雨溪推荐大家用axios替换JQuery ajax,想必让axios进入了很多人的目光中。

axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,本质上也是对原生XHR的封装,只不过它是Promise的实现版本,符合最新的ES规范,它本身具有以下特征:

1.从浏览器中创建 XMLHttpRequest
2.支持 Promise API
3.客户端支持防止CSRF
4.提供了一些并发请求的接口(重要,方便了很多的操作)
5.从 node.js 创建 http 请求
6.拦截请求和响应
7.转换请求和响应数据
8.取消请求
9.自动转换JSON数据

对于 axios 的一些其他问题在上一篇文章中有了详细的说明。

三、fetch

fetch号称是AJAX的替代品,是在ES6出现的,使用了ES6中的promise对象。Fetch是基于promise设计的。Fetch的代码结构比起ajax简单多了,参数有点像jQuery ajax。但是,一定记住fetch不是ajax的进一步封装,而是原生js,没有使用XMLHttpRequest对象。
fetch的优点
1.符合关注分离,没有将输入、输出和用事件来跟踪的状态混杂在一个对象里
2.更好更方便的写法


坦白说,上面的理由对我来说完全没有什么说服力,因为不管是Jquery还是Axios都已经帮我们把xhr封装的足够好,使用起来也足够方便,为什么我们还要花费大力气去学习fetch?
我认为fetch的优势主要优势就是:

1.语法简洁,更加语义化
2.基于标准 Promise 实现,支持 async/await
3.更加底层,提供的API丰富(request, response)
4.脱离了XHR,是ES规范里新的实现方式


最近在使用fetch的时候,也遇到了不少的问题
fetch是一个低层次的API,你可以把它考虑成原生的XHR,所以使用起来并不是那么舒服,需要进行封装。
例如:

1)fetch只对网络请求报错,对400,500都当做成功的请求,服务器返回 400,500 错误码时并不会 reject,只有网络错误这些导致请求不能完成时,fetch 才会被 reject。
2)fetch默认不会带cookie,需要添加配置项: fetch(url, {credentials: 'include'})
3)fetch不支持abort,不支持超时控制,使用setTimeout及Promise.reject的实现的超时控制并不能阻止请求过程继续在后台运行,造成了流量的浪费
4)fetch没有办法原生监测请求的进度,而XHR可以

fetch 示例:

      fetch(url, {
        method: 'post',
        mode: 'cors', // no-cors, cors, *same-origin,设置跨域
        credentials: 'include',    // 携带 cookie,还有same-origin、omit 设置
        headers: new Headers({
          // 'Content-Type': 'application/x-www-form-urlencoded'
          'Content-Type': 'application/json'
        }),
        body: JSON.stringify(this.writeData)
      }).then(res => {
        return res.json()   // 返回的json,需要这样处理下才可以接收到,get、post都需要
      }).then(response => {
        console.log('fetch response', response)
        if (response.code === 200 && response.data) {
          this.$message.success(response.msg)
        } else {
          this.$message.error(response.msg)
        }
      })

鉴于此,在一些小的项目中,或者像我这样只是一个示例的时候,直接用 fetch ,很方便,因为是原生的不需要引用什么等。

 

参考:https://www.jianshu.com/p/8bc48f8fde75

posted @ 2019-11-26 14:32  漠里  阅读(660)  评论(0编辑  收藏  举报