// 通用请求封装
async function request(url, options = {}) {
// 1. 统一配置默认值
const defaultOptions = {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest',
// 统一加token(后端最常用的认证方式)
'Authorization': `Bearer ${localStorage.getItem('token') || ''}`
},
credentials: 'include' // 自动携带cookie(解决跨域session问题)
};
// 2. 合并用户配置
const finalOptions = {...defaultOptions, ...options, headers: {...defaultOptions.headers, ...options.headers}};
// 3. 自动处理POST请求的body
if (finalOptions.body && typeof finalOptions.body === 'object') {
finalOptions.body = JSON.stringify(finalOptions.body);
}
try {
if (http.ing) {
throw new Error('请勿频繁点击');
}
http.ing = true;
// 4. 发送请求
const response = await fetch(url, finalOptions);
http.ing = false;
// 5. 统一处理HTTP错误(Fetch默认4xx/5xx不抛异常,这是最大的坑)
if (!response.ok) {
console.log(response)
throw new Error(`HTTP错误: ${response.status} ${response.statusText}`);
}
// 6. 统一解析响应
const data = await response.json();
if (data.code === 0) {
if (typeof successMsg === 'function') {
successMsg(data.msg);
}
} else {
throw new Error(data.msg || '业务请求失败');
}
// 8. 返回 data
return data.data;
} catch (error) {
// 9. 统一错误提示(不用每个请求都写catch)
if (typeof errorMsg === 'function') {
errorMsg(error.message);
} else {
alert(error.message);
}
throw error; // 可选:抛出错误让调用方继续处理
}
}
// 二次封装常用的HTTP方法(和后端Controller对齐)
const http = {
get: (url, params) => {
const query = new URLSearchParams(params).toString();
request(query ? url + '?' + query : url)
},
post: (url, data) => request(url, {method: 'POST', body: data}),
put: (url, data) => request(url, {method: 'PUT', body: data}),
delete: (url) => request(url, {method: 'DELETE'}),
ing: false
};