// 创建XHR对象const xhr = new XMLHttpRequest();// 配置请求(method, url, async)xhr.open('GET', '/api/data', true);// 设置请求头(可选)xhr.setRequestHeader('Content-Type', 'application/json');// 监听状态变化xhr.onreadystatechange = function() {if (xhr.readyState === 4) { // 完整响应if (xhr.status >= 200 && xhr.status < 300) { // 成功状态码const responseData = JSON.parse(xhr.responseText);handleResponse(responseData);} else {handleError(xhr.status);}}};// 发送请求(带请求体)xhr.send(JSON.stringify({ key: 'value' }));fetch('/api/data', {method: 'GET',headers: {'Content-Type': 'application/json',},body: JSON.stringify({ key: 'value' }),mode: 'cors', // 跨域策略credentials: 'include' // 携带Cookie}).then(response => {if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);return response.json(); // 自动解析JSON响应}).then(data => handleResponse(data)).catch(error => handleError(error));|
特性 |
XMLHttpRequest |
Fetch API |
|
语法风格 |
过程式 |
函数式 + 声明式 |
|
错误处理 |
依赖状态码检查 |
显式 Promise reject |
|
并发支持 |
需手动管理 |
原生支持 Promise.all |
|
浏览器兼容性 |
全版本支持 |
IE 不支持(需 polyfill) |
|
中止请求 |
xhr.abort() |
AbortController |
// XHR回调示例xhr.onload = function() { /* 成功处理 */ };xhr.onerror = function() { /* 错误处理 */ };// 封装XHR为Promisefunction fetchWithXHR(url) {return new Promise((resolve, reject) => {const xhr = new XMLHttpRequest();xhr.open('GET', url);xhr.onload = () => xhr.status >= 200 && xhr.status < 300 ? resolve(xhr.response) : reject(xhr.status);xhr.onerror = () => reject('Network error');xhr.send();});}// 使用async/await处理Fetchasync function loadData() {try {const response = await fetch('/api/data');if (!response.ok) throw new Error(`HTTP Error: ${response.status}`);const data = await response.json();return data;} catch (error) {console.error('Fetch failed:', error);throw error; // 向上传递错误}}// Fetch网络错误(断网、跨域被阻止等)fetch('/api/data').then(response => response.json()).catch(error => {if (error.name === 'AbortError') {console.log('请求已中止');} else if (error instanceof TypeError) {console.log('网络请求失败');}});// XHR网络错误xhr.onerror = function() {console.log('网络连接失败');};// 统一处理非2xx状态码function checkStatus(response) {if (response.ok) {return response;} else {const error = new Error(`HTTP Status: ${response.status}`);error.response = response;throw error; // 抛出异常到catch}}// 使用示例fetch('/api/data').then(checkStatus).then(response => response.json());// Fetch中止请求(AbortController)const controller = new AbortController();const signal = controller.signal;fetch('/api/data', { signal }).then(response => response.json()).catch(error => {if (error.name === 'AbortError') {console.log('请求已中止');}});// 中止请求controller.abort();// XHR中止请求xhr.abort();// 统一请求配置(以Axios为例)const instance = axios.create({baseURL: 'https://api.example.com',timeout: 5000, // 5秒超时headers: {'X-Requested-With': 'XMLHttpRequest','Authorization': `Bearer ${getToken()}`}});let isLoading = false;async function fetchData() {if (isLoading) return; // 防止重复请求isLoading = true;try {showLoadingIndicator();const response = await fetch('/api/data');// 处理响应} finally {hideLoadingIndicator();isLoading = false;}}// 响应数据验证function validateData(data) {if (typeof data.id !== 'number' || !data.name) {throw new Error('Invalid response data');}return data;}// 使用示例fetch('/api/data').then(response => response.json()).then(validateData);// 全局请求日志fetch('/api/data').then(response => {console.log(`[API Request] Success: ${response.url}`);return response.json();}).catch(error => {console.error(`[API Request] Failed: ${error.message}`);analytics.track('API_ERROR', { url: error.config.url, code: error.response.status });});
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70046748/viewspace-3088313/ ,如需转载,请注明出处,否则将追究法律责任。