JS fetch接口请求实战指南
在现代Web开发中,与后端接口的数据交互是核心环节。从早期的XMLHttpRequest到如今的fetch API,前端请求方式不断演进。fetch作为原生浏览器API,凭借简洁的Promise语法和灵活的配置能力,逐渐成为异步请求的首选方案。本文将从基础用法到高级技巧,全面解析JS fetch接口请求的实战要点,帮助开发者高效处理数据交互。
一、fetch基础用法:从入门到掌握
fetch()是浏览器原生提供的接口请求方法,调用时返回一个Promise对象,处理异步请求结果。基础语法如下:
// GET请求示例:获取用户列表
fetch('https://api.example.com/users')
.then(response => {
// 处理响应数据
if (!response.ok) {
throw new Error(`请求失败,状态码:${response.status}`);
}
return response.json(); // 解析JSON格式响应
})
.then(data => console.log('用户数据:', data))
.catch(error => console.error('请求错误:', error.message));
核心参数解析:
fetch(url, init)的第二个参数init是可选配置对象,包含请求方法、头信息、请求体等:
method:请求方法(GET/POST/PUT/DELETE等)headers:请求头(如Content-Type、Token、Cookie)body:请求体(仅POST/PUT等方法使用,需为字符串或FormData等)credentials:是否携带Cookie(same-origin/cors/include)
POST请求示例:发送JSON数据到服务器
const userData = { name: '张三', age: 25 };
fetch('https://api.example.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json', // 声明JSON格式
'Authorization': 'Bearer YOUR_TOKEN' // 身份验证
},
body: JSON.stringify(userData) // 请求体需转为JSON字符串
})
.then(response => response.json())
.then(result => console.log('创建用户成功:', result));
二、常见场景:解决90%的接口请求问题
1. 请求参数传递
- GET请求参数:直接拼接URL(查询字符串)
const userId = 1; fetch(`https://api.example.com/users/${userId}?include=posts`) - POST请求数据格式:支持JSON、FormData、URLSearchParams等
- FormData(上传文件或表单数据):
const formData = new FormData(); formData.append('avatar', fileInput.files[0]); // 添加文件 formData.append('username', 'test'); // 添加文本 fetch('https://api.example.com/upload', { method: 'POST', body: formData // FormData无需手动设置Content-Type });
- FormData(上传文件或表单数据):
2. 错误处理:避免请求“静默失败”
fetch仅在网络故障时抛出错误,HTTP错误(如404、500)需手动判断:
fetch('https://api.example.com/data')
.then(response => {
// 手动处理HTTP错误状态码
if (!response.ok) {
if (response.status === 401) {
// 未授权:跳转登录页
window.location.href = '/login';
}
throw new Error(`HTTP错误:${response.status}`);
}
return response.json();
})
.catch(error => {
if (error.name === 'TypeError' && error.message.includes('Failed to fetch')) {
// 网络错误:提示用户检查连接
alert('网络连接失败,请重试');
}
});
3. 异步/同步语法:async/await简化代码
结合async/await可将异步代码写得更接近同步逻辑:
async function getUserData(userId) {
try {
const response = await fetch(`https://api.example.com/users/${userId}`);
const user = await response.json();
return user; // 返回结果供上层调用
} catch (error) {
console.error('获取用户数据失败:', error);
return null; // 错误时返回默认值
}
}
// 使用示例
getUserData(1).then(user => console.log('用户信息:', user));
三、高级技巧:突破基础限制的实战能力
1. 中断请求:AbortController的应用
当用户离开页面、组件卸载或请求超时后,可通过AbortController取消请求:
const controller = new AbortController();
const signal = controller.signal;
// 发起请求时传入signal
const fetchData = fetch('https://api.example.com/large-data', { signal });
// 取消请求(如用户点击“取消”按钮)
document.getElementById('cancel-btn').addEventListener('click', () => {
controller.abort(); // 终止请求
console.log('请求已取消');
});
fetchData.catch(error => {
if (error.name === 'AbortError') {
// 捕获取消错误
console.log('请求被主动取消');
}
});
2. 请求拦截与封装:统一处理通用逻辑
通过封装fetch函数,可实现Token自动添加、错误重试、日志打印等通用逻辑:
function fetchWithAuth(url, options = {}) {
// 1. 自动添加Token
const token = localStorage.getItem('token');
const headers = {
'Content-Type': 'application/json',
...options.headers,
...(token && { 'Authorization': `Bearer ${token}` })
};
return fetch(url, { ...options, headers })
.then(response => {
// 2. 统一错误状态码处理
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return response.json();
})
.catch(error => {
// 3. 错误重试(示例:网络错误时重试1次)
if (error.name === 'TypeError' && options.retry) {
return fetchWithAuth(url, { ...options, retry: false });
}
return Promise.reject(error);
});
}
// 使用示例
fetchWithAuth('https://api.example.com/data', { method: 'GET' });
3. 并发请求:Promise.all的高效应用
当需要同时获取多个接口数据时,使用Promise.all并行请求:
async function loadDashboardData() {
const [userResponse, statsResponse] = await Promise.all([
fetch('https://api.example.com/dashboard/user'),
fetch('https://api.example.com/dashboard/stats')
]);
const user = await userResponse.json();
const stats = await statsResponse.json();
return { user, stats }; // 聚合结果
}
loadDashboardData().then(data => console.log('仪表盘数据:', data));
四、最佳实践:让请求更健壮、更高效
1. 错误分类与用户体验
- 网络错误:提示“网络连接失败,请检查网络设置”
- 401未授权:自动跳转登录页
- 404资源不存在:显示“数据不存在”提示
- 500服务器错误:提示“服务器维护,请稍后重试”
2. 请求合并与节流
对高频触发的请求(如搜索输入),使用防抖/节流减少请求次数:
// 防抖函数:300ms内只触发一次请求
function debounceFetch(url, delay = 300) {
let timeoutId;
return (...args) => {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
fetch(url, ...args);
}, delay);
};
}
const searchFetch = debounceFetch('https://api.example.com/search');
// 输入事件触发时调用searchFetch
input.addEventListener('input', (e) => searchFetch(e.target.value));
3. 响应缓存:提升性能的关键
结合Cache API缓存请求结果,避免重复请求:
async function fetchWithCache(url) {
const cacheKey = `cache_${url}`;
const cachedData = localStorage.getItem(cacheKey);
// 优先读取缓存
if (cachedData) {
return JSON.parse(cachedData);
}
// 缓存未命中时请求接口
const response = await fetch(url);
const data = await response.json();
// 存入缓存(设置10分钟过期)
localStorage.setItem(cacheKey,
文章版权声明:除非注明,否则均为Dark零点博客原创文章,转载或复制请以超链接形式并注明出处。

