区别
特性 | ajax | axios | fetch |
---|---|---|---|
基于标准 | 基于XMLHttpRequest对象 | 基于Promise的HTTP客户端,本质上也是对原生XMLHttpRequest的封装 | 基于Promise的HTTP客户端,Web API的一部分 |
浏览器兼容性 | ☆☆☆☆☆ | ☆☆☆☆ | ☆☆☆ |
使用方式 | 原生JavaScript、jQuery等库封装 | 独立的npm包,可在Node.js和浏览器中使用 | 原生JavaScript API |
错误处理 | 需要手动处理XMLHttpRequest对象的错误事件 | 提供.catch() 方法捕获Promise异常 | 提供.catch() 方法捕获Promise异常 |
请求取消 | 需要额外实现(如使用AbortController polyfill) | 提供.CancelToken 源取消请求 | 提供AbortController 和AbortSignal 接口来取消请求 |
请求和响应拦截 | 需要手动处理 | 提供请求和响应拦截器 | 需要手动处理或使用Service Workers |
请求超时 | 需要手动设置超时时间 | 提供超时配置选项 | 需要手动处理或使用Service Workers |
自动转换JSON | 需要手动处理响应数据 | 自动将JSON响应转换为JavaScript对象 | 自动将JSON响应转换为JavaScript对象 |
数据类型 | 支持多种数据类型(如文本、XML、JSON等) | 主要支持JSON数据 | 主要支持JSON数据 |
简单通俗来讲:
-
axios是通过promise实现对ajax技术的一种封装。
-
ajax技术实现了网页的局部数据刷新,axios实现了对ajax的封装。
-
axios是ajax , ajax不止axios
ajax
它的全称是:Asynchronous JavaScript And XML
,翻译过来就是“异步的 Javascript 和 XML”。
很多小伙伴可能会误以为 Ajax 是发请求的一种方式,或者把 XMLHttpRequest 与 Ajax 划等号,其实这是错误和片面的。
Ajax 是一个技术统称,是一个概念模型,它囊括了很多技术,并不特指某一技术,它很重要的特性之一就是让页面实现局部刷新。
ajax是js异步技术的术语,早起相关的api是xhr,它是一个术语。
简单来说,Ajax 是一种思想,XMLHttpRequest
只是实现 Ajax 的一种方式。其中 XMLHttpRequest 模块就是实现 Ajax 的一种很好的方式。
<body>
<script>
function ajax(url) {
const xhr = new XMLHttpRequest();
xhr.open("get", url, false);
xhr.onreadystatechange = function () {
// 异步回调函数
if (xhr.readyState === 4) {
if (xhr.status === 200) {
console.info("响应结果", xhr.response)
}
}
}
xhr.send(null);
}
ajax('https://smallpig.site/api/category/getCategory')
</script>
</body>
$.ajax
$.ajax({
type: 'get',
url: '/getuser/data',
dataType: 'json',
data: {
firstName: '张',
lastName: '三'
},
success: function (response) {
console.log(response);
},
error: function (error) {
console.log(error);
}
});
传统 Ajax 指的是 XMLHttpRequest(XHR)
, 最早出现的发送后端请求技术,隶属于原始js中,核心使用XMLHttpRequest
对象,多个请求之间如果有先后关系的话,就会出现回调地狱
。
JQuery ajax 是对原生XHR的封装
,除此以外还增添了对JSONP
的支持。经过多年的更新维护,真的已经是非常的方便了,优点无需多言;如果是硬要举出几个缺点,那可能只有:
- 本身是针对MVC的编程,不符合现在前端MVVM的浪潮
- 基于原生的XHR开发,XHR本身的架构不清晰。
- JQuery整个项目太大,单纯使用ajax却要引入整个JQuery非常的不合理(采取个性化打包的方案又不能享受CDN服务)
- 不符合关注分离(Separation of Concerns)的原则
- 配置和调用方式非常混乱,而且基于事件的异步模型不友好。
手写一个简单的ajax
var xhr = new XMLHttpRequest(); // 声明一个请求对象
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){ // readyState 4 代表已向服务器发送请求
if(xhr.status === OK){ // // status 200 代表服务器返回成功
console.log(xhr.responseText); // 这是返回的文本
} else{
console.log("Error: "+ xhr.status); // 连接失败的时候抛出错误
}
}
}
xhr.open('GET', 'xxxx');
// 如何设置请求头? xhr.setRequestHeader(header, value);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(null); // get方法 send null(亦或者不传,则直接是传递 header) ,post 的 send 则是传递值
axios
Axios 是一个基于 promise 封装的网络请求库,它是基于 XHR 进行二次封装。
axios({
method: 'get',
url: '/getuser/data',
responseType: 'json',
data: {
firstName: '张',
lastName: '三'
}
}).then(function (response) {
console.log(response);
}).catch(function (error) {
console.log(error);
});
Vue2.0之后,尤雨溪推荐大家用axios替换JQuery ajax,想必让axios进入了很多人的目光中。
axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,本质上也是对原生XHR的封装,只不过它是Promise的实现版本,符合最新的ES规范,它本身具有以下特征:
- 基于 Promise
- 浏览器和 Node.js 都支持
- 拦截请求和响应(axios鉴权)
- 自动转换 JSON 数据
- 转换请求和响应数据
- 取消请求
- 广泛的配置选项
- 客户端支持防止 CSRF/XSRF
- 支持 HTTP 授权
- 良好的错误处理
需要注意:
-
axios和vue没关系,axios也不是随着Vue的兴起才广泛使用的,axios本身就是独立的请求库,跟用什么框架没关系;而且最初Vue官方推荐的请求库是vue-resouce,后来才推荐的axios;
-
axios不是xhr的子集,axios利用xhr进行了二次封装的请求库,xhr只是axios中的其中一个请求适配器,axios在nodejs端还有个http的请求适配器;axios = xhr + http;
fetch
- fetch() 方法用于发起获取(或发送)资源的请求。它返回一个Promise,这个Promise并不会直接返回数据结果,而是联系服务器。
- 联系服务器:第一个then()用于处理fetch的响应对象,可以通过检查
response.ok
来判断请求是否成功(状态码200-299)。 - 获取数据:第二个then()用于处理响应体的数据。这里调用了
response.json()
方法,它也会返回一个Promise,该Promise在JSON解析完成后被resolve。 catch()
用于捕获并处理在Promise链中发生的任何错误。
注意:fetch默认不会发送或接收任何cookies,如果需要发送cookies,需要设置 credentials
选项,如:fetch(url, { credentials: 'include' })
const getData = () => {
// fetch() 返回一个Promise,该Promise在请求成功时解析为Response对象
fetch('https://api.example.com/data')
.then(response => { // 第一个then():联系服务器
console.log('联系服务器成功');
// 调用response.json()方法将其解析为JavaScript对象
return response.json(); // response.json()也返回一个Promise
})
.then(data => { console.log('获取数据成功', data); }) // 第二个then():获取数据
.catch(error => { console.error('请求失败', error); }); // 捕获在上述任何步骤中抛出的错误
};
用 async
、await
优化下:
const getData = async () => {
try {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
console.log('获取数据成功', data);
} catch (error) {
console.error('请求失败:', error);
}
};