XHR(XMLHttpRuest)和fetch请求再JavaScript中都是用于发起网络请求的,但是存在一定的差异性;
- 起源和兼容性
XHR是最早期的浏览器提供的原生API,在后续的使用过程中出现了axios的封装。由于它的历史比较久远,所以XHR在旧版的浏览器中具有更好的兼容性;
Fetch是ES6新增的全局函数,它的出现旨在替代XHR(但是目前还是使用XHR请求的比较多)。但是由于它属于较新的技术,会存在浏览器版本兼容问题;
- 使用和处理方式
XHR是使用XMLHttpRequest对象来处理请求和响应。它通常使用回调函数来处理异步操作,并通过设置事件处理程序来监听请求的状态变化。在处理多个异步请求时,可能需要使用回调嵌套或其他处理方式。
注:本文主要描述原生的XHR,在axios中,有了Promise技术,基本不再使用回调函数的形式处理请求结果。
Fetch:使用Promise对象来处理请求和响应,这使得异步处理更加直观和易于管理。Fetch方法返回一个Promise,可以链式调用.then()来处理响应,或使用async/await语法使代码更加简洁。
try {
const response = await fetch(`/api1/search/users2?q=${value}`);
const data = await response.json();
console.log(data);
PubSub.publish("weiyonghui", { isLoading: false, users: data.items });
} catch (error) {
console.log('请求出错',error);
PubSub.publish("weiyonghui", { isLoading: false, users: error.message });
}
- Cookies处理
XHR:会自动携带cookies,这在进行需要身份验证的请求时非常方便。
Fetch:目前原生fetch API没有提供请求取消的机制,但可以通过其他手段(如AbortController)实现。
注:关于Fetch的二次封装
// 创建一个封装后的fetch函数
function customFetch(url, options) {
// 合并默认选项和传入选项
const defaultOptions = {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
credentials: 'include', // 携带cookies
};
const mergedOptions = { ...defaultOptions, ...options };
// 添加请求拦截器逻辑(如果需要)
// ...
// 发送请求
return fetch(url, mergedOptions)
.then(response => {
// 响应状态码判断
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
// 根据不同的Content-Type解析响应体
if (response.headers.get('content-type').includes('application/json')) {
return response.json();
} else {
return response.text();
}
})
.catch(error => {
// 错误处理逻辑
if (error.name === 'AbortError') {
console.log('Fetch aborted');
} else {
console.error('Fetch error:', error);
}
throw error;
});
}
- 请求取消
XHR:可以使用xhr.abort()
来取消请求。
Fetch:原生fetch API不提供取消请求的功能,但可以通过AbortController
来实现。
注:接上面的封装
// 取消fetch请求(如果需要)
const controller = new AbortController();
const signal = controller.signal;
customFetch('https://example.com/api/slow-data', { signal })
.then(data => {
// ...
})
.catch(error => {
if (error.name === 'AbortError') {
console.log('Fetch request has been aborted');
}
});
// 在某个时机取消请求
controller.abort();
- 响应处理
XHR:响应数据以字符串形式提供,需要手动解析为JSON或其他格式。
Fetch:返回的是一个Response对象,可以使用.json()
, .text()
, .blob()【一定要调用】
等方法来解析响应数据。
- 进度监听(上传文件||下载文件)
XHR:可以使用xhr.upload.onprogress
和xhr.onprogress
来监听上传和下载的进度。(axios中进行了封装)
Fetch:原生fetch API不支持进度监听。
- 请求配置
XHR:通过直接设置XHR对象的属性和方法来配置请求,如设置请求头、请求体等。
Fetch:通过传递一个配置对象给fetch函数来配置请求,该对象可以包含方法、头、体等信息。