在JavaScript前端开发中,网络请求是实现数据交互的基础能力,Axios和Fetch API是当下最主流的两种请求实现方案。除了基础的发送GET、POST请求之外,两者都提供了丰富的高级特性,能够应对复杂业务场景下的请求处理需求。

Axios高级用法
拦截器配置
Axios的拦截器可以在请求发送前或响应返回后对数据进行处理,常用于统一添加请求头、处理token过期、统一错误提示等场景。
// 创建Axios实例
const instance = axios.create({
baseURL: 'https://ipipp.com/api',
timeout: 5000
});
// 请求拦截器
instance.interceptors.request.use(
config => {
// 统一添加Authorization请求头
const token = localStorage.getItem('token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
error => {
return Promise.reject(error);
}
);
// 响应拦截器
instance.interceptors.response.use(
response => {
// 只返回接口返回的业务数据
return response.data;
},
error => {
// 统一处理错误提示
if (error.response) {
switch (error.response.status) {
case 401:
alert('登录已过期,请重新登录');
break;
case 500:
alert('服务器内部错误');
break;
default:
alert('请求失败,请稍后重试');
}
}
return Promise.reject(error);
}
);
取消重复请求
在用户快速重复点击按钮的场景下,会产生多个相同的请求,既浪费资源也可能导致数据异常,Axios可以通过请求取消功能避免这类问题。
// 存储正在进行的请求
const pendingRequests = new Map();
// 生成请求的唯一标识
const getRequestKey = config => {
return `${config.method}-${config.url}-${JSON.stringify(config.params || {})}-${JSON.stringify(config.data || {})}`;
};
// 添加请求到pending
const addPendingRequest = config => {
const requestKey = getRequestKey(config);
if (!pendingRequests.has(requestKey)) {
config.cancelToken = new axios.CancelToken(cancel => {
pendingRequests.set(requestKey, cancel);
});
}
};
// 移除已完成的请求
const removePendingRequest = config => {
const requestKey = getRequestKey(config);
if (pendingRequests.has(requestKey)) {
const cancel = pendingRequests.get(requestKey);
cancel(`重复请求已取消:${requestKey}`);
pendingRequests.delete(requestKey);
}
};
// 在拦截器中应用
instance.interceptors.request.use(
config => {
removePendingRequest(config);
addPendingRequest(config);
return config;
},
error => Promise.reject(error)
);
instance.interceptors.response.use(
response => {
removePendingRequest(response.config);
return response.data;
},
error => {
if (error.config) {
removePendingRequest(error.config);
}
return Promise.reject(error);
}
);
并发请求处理
Axios提供了axios.all和axios.spread方法,可以处理多个并发请求,等待所有请求完成后统一处理返回结果。
// 定义两个请求函数
const getUserInfo = () => instance.get('/user/info');
const getOrderList = () => instance.get('/order/list');
// 并发发送请求
axios.all([getUserInfo(), getOrderList()])
.then(axios.spread((userRes, orderRes) => {
console.log('用户信息:', userRes);
console.log('订单列表:', orderRes);
}))
.catch(error => {
console.error('请求失败:', error);
});
Fetch API高级用法
请求超时控制
Fetch API本身不支持超时配置,需要结合Promise.race方法实现超时控制逻辑。
// 封装带超时的Fetch请求
const fetchWithTimeout = (url, options = {}, timeout = 5000) => {
// 创建超时Promise
const timeoutPromise = new Promise((_, reject) => {
setTimeout(() => {
reject(new Error('请求超时'));
}, timeout);
});
// 发起Fetch请求
const fetchPromise = fetch(url, options);
// 竞争两个Promise,先完成的返回结果
return Promise.race([fetchPromise, timeoutPromise]);
};
// 使用示例
fetchWithTimeout('https://ipipp.com/api/user/list', {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
}, 3000)
.then(response => {
if (!response.ok) {
throw new Error(`请求失败,状态码:${response.status}`);
}
return response.json();
})
.then(data => {
console.log('返回数据:', data);
})
.catch(error => {
console.error('请求错误:', error.message);
});
自定义请求头与请求体
Fetch API可以通过headers配置自定义请求头,支持发送JSON、FormData等多种格式的请求体。
// 发送JSON格式请求体
const postJsonData = async () => {
try {
const response = await fetch('https://ipipp.com/api/user/add', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${localStorage.getItem('token')}`
},
body: JSON.stringify({
name: '张三',
age: 25
})
});
const data = await response.json();
console.log('添加结果:', data);
} catch (error) {
console.error('请求失败:', error);
}
};
// 发送FormData格式请求体(常用于文件上传)
const uploadFile = async (file) => {
const formData = new FormData();
formData.append('file', file);
formData.append('type', 'avatar');
try {
const response = await fetch('https://ipipp.com/api/upload', {
method: 'POST',
body: formData
// 注意:发送FormData时不要手动设置Content-Type,浏览器会自动设置正确的边界
});
const data = await response.json();
console.log('上传结果:', data);
} catch (error) {
console.error('上传失败:', error);
}
};
流式数据处理
Fetch API支持读取流式响应数据,适合处理大文件下载、实时数据推送等场景,不需要等待所有数据加载完成再处理。
// 读取流式响应
const readStreamData = async () => {
try {
const response = await fetch('https://ipipp.com/api/stream/data');
const reader = response.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) {
console.log('流式数据读取完成');
break;
}
// 解码当前读取的片段
const chunk = decoder.decode(value, { stream: true });
console.log('当前片段数据:', chunk);
}
} catch (error) {
console.error('读取失败:', error);
}
};
两者对比与场景选择
| 特性 | Axios | Fetch API |
|---|---|---|
| 浏览器兼容性 | 兼容IE11及以上,支持更多旧环境 | 不支持IE,现代浏览器原生支持 |
| 拦截器 | 内置拦截器,配置简单 | 无内置拦截器,需要手动封装 |
| 请求取消 | 内置CancelToken支持 | 需要结合AbortController实现 |
| 响应处理 | 自动转换JSON数据,自动处理错误状态码 | 需要手动调用json()等方法,不会自动抛出HTTP错误 |
| 依赖情况 | 需要安装第三方包 | 浏览器原生支持,无需额外依赖 |
如果项目需要兼容旧浏览器,或者需要快速实现拦截、请求取消等高级特性,优先选择Axios;如果是现代浏览器环境,且希望减少第三方依赖,Fetch API是更合适的选择,只需要额外封装部分通用逻辑即可满足需求。
AxiosFetch_APIJavaScript网络请求修改时间:2026-06-23 16:09:50