从事前端也有段时间了,发送请求也是家常便饭,最近接手一个项目,出现用fetch会有未知bug产生,当我换成Axios以后就好了,所以就打算捋一下Ajax、Axios和Fetch,也算让自己更了解一下自己从事的工作吧。
简介
Ajax
AJAX(Asynchronous JavaScript and XML),指的是一套综合了多项技术的浏览器端网页开发技术。Ajax的概念由杰西·詹姆士·贾瑞特所提出。我个人理解就是页面有数据变化不用整个页面刷新,而是可以进行异步请求再通过JS进行数据更换。在现代浏览器上写AJAX主要依靠XMLHttpRequest对象。
Axios
可以把Promise用在node和HTTP客户端
Fetch
提供了一个 JavaScript接口,用于访问和操纵HTTP管道的部分,例如请求和响应。它还提供了一个全局fetch()
方法,该方法提供了一种简单,合理的方式来跨网络异步获取资源。
兼容性
Ajax
Fetch
- Supported 支持
- Not supported 不支持
- Partial support 部分支持
- Support unknown 支持情况未知
Axios
总结
我们不看Axios这个库,但就Ajax和fetch这两个,Ajax的兼容性要好于Fetch,Axios的兼容性我觉得首先取决于Ajax的兼容性,其次是取决于开发者的适配了,所以我觉得兼容性方面是Fetch<Axios<Ajax
实现
Ajax
var xmlhttp;
if (window.XMLHttpRequest){
// IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
xmlhttp=new XMLHttpRequest();
} else {
// IE6, IE5 浏览器执行代码
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState==4 && xmlhttp.status==200){
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","url",true);
xmlhttp.send();
从这我们就能看出来,原生的Ajax很不好理解,甚至有的面试官在面试的时候会让我们手写Ajax请求,我觉得Ajax请求原理我们做前端的是一点要知道的,但是,我们在工作中不能这些,一是不方便,二是很容易出错,所以我们可以选择JQ来帮助我们
jQuery Ajax
$.ajax({
type: 'POST',
url: url,
data: data,
dataType: dataType,
success: function() {},
error: function() {}
})
从JQ封装好的Ajax请求来看,结构清晰,简单明了,并且JQ已经帮我们处理好了兼容性的问题,所以我们可以大胆的使用,但是有一点,如果你只是为了一个Ajax而引用一个jQuery库的话,未压缩的有266kb,压缩以后也有86kb,显然有点小题大做,杀鸡焉用宰牛刀。
Axios
const axios = require('axios');
// Make a request for a user with a given ID
axios.get('/user?ID=12345')
.then(function (response) {
// handle success
console.log(response);
})
.catch(function (error) {
// handle error
console.log(error);
})
.then(function () {
// always executed
});
axios.post('/user', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
Axios的结构也很明了,并且引入了Promise,在处理上没有了回调地狱,在错误处理上也使用了.catch()
,可以说是相当方便了
Fetch
fetch('http://example.com/movies.json')
.then(function(response) {
return response.json();
})
.then(function(myJson) {
console.log(JSON.stringify(myJson));
});
这么看来的话,貌似Fetch的使用也很清晰,但是我们往下看
对比
在此使用jQuery Ajax还代替原生Ajax来参加比赛;
jQuery Ajax在经过jQuery近十来年的更新维护,已经可以说使用非常方便,在便捷性、兼容性和使用上差不多没什么可以挑剔了,But
- 本身是针对MVC的编程,不符合现在前端MVVM的浪潮
- 基于原生的XHR开发,XHR本身的架构不清晰,已经有了fetch的替代方案
- JQuery整个项目太大,单纯使用ajax却要引入整个JQuery非常的不合理(采取个性化打包的方案又不能享受CDN服务)
虽然jQuery在前端领域经理过辉煌,现在也不乏“老夫只用jQuery”的梗来调侃jQuery的过时,但是它的成功是不可否定的,可没有跟上前端快速发展的步伐,就像诺基亚一样,什么都没有做错,但这就是唯一做错的地方,一代巨人也会倒下
Aioxs虽然本质上也是对XHR的高级封装,并支持了Promise,符合最新的ECMA规范,就github上的介绍:
- Make XMLHttpRequests from the browser // 可以从浏览器发起XHR请求
- Make http requests from node.js // 从 node.js 创建 http 请求
- Supports the Promise API // 支持Promise API
- Intercept request and response // 拦截请求和响应
- Transform request and response data // 转换请求和响应数据
- Cancel requests // 取消请求
- Automatic transforms for JSON data // 自动转换JSON数据
- Client side support for protecting against XSRF // 支持客户端防止XSRF攻击
Axios也完成了各种封装,并且大小也只有4.5kb,已经很小了,并且还有并发的封装,现在看来Axios是个不错的选择;
由于Fetch API是基于Promise设计,旧浏览器不支持Promise,并且Fetch比较偏底层,相对于Axios和jQuery Ajax来说,没有过多的封装,在使用上自然没有他们方便,而且没有封装过的Fetch还有很多不足之处
- Fetch默认不携带cookie信息,需要设置
credentials: 'include'
- 服务器返回 400,500 错误码时并不会 reject,只有网络错误这些导致请求不能完成时,fetch 才会被 reject
- 因为Fetch基于Promise,所以会有很多Promise的未知bug
但是Fetch得优点依然会有:
- 脱离了XHR,是ES规范里新的实现方式
- 更加底层,提供的API丰富(request, response)
- 符合关注分离,没有将输入、输出和用事件来跟踪的状态混杂在一个对象里
- 更好更方便的写法
总结
Ajax虽然年老,但是用他肯定不会有兼容性的问题,可jQuery太大,貌似会拖累前端前进的步伐。而Fetch尚还年轻,大环境对他来说可以生存,可不能很好的生活下去,但以后肯定会发光发热,未来是属于Fetch的。现在我们大可以放心使用Axios,成熟,轻量,API简单,正当年的时候,用他准没错。
本文带有个人偏见,不对的地方请指正
参考
《传统 Ajax 已死,Fetch 永生》
《Jquery ajax, Axios, Fetch区别之我见》
《Fetch vs Axios http request》