71 lines
1.8 KiB
JavaScript
71 lines
1.8 KiB
JavaScript
// 根据环境自动选择API地址
|
||
const BASE_URL = '';
|
||
// 使用相对路径,所有 API 请求会自动走当前域名下的 Nginx 代理,避免 CORS 问题
|
||
|
||
|
||
|
||
// 工具函数:获取token
|
||
export function getToken() {
|
||
return localStorage.getItem('token') || '';
|
||
}
|
||
|
||
// 通用fetch,自动加Authorization
|
||
export async function authFetch(url, options = {}) {
|
||
const token = getToken();
|
||
const headers = {
|
||
'Content-Type': 'application/json',
|
||
...(options.headers || {}),
|
||
...(token ? { Authorization: `Bearer ${token}` } : {})
|
||
};
|
||
|
||
// 如果有body且是对象,转换为JSON字符串
|
||
if (options.body && typeof options.body === 'object') {
|
||
options.body = JSON.stringify(options.body);
|
||
}
|
||
|
||
try {
|
||
const response = await fetch(`${BASE_URL}${url}`, {
|
||
...options,
|
||
headers,
|
||
credentials: 'include' // 添加这个以支持跨域请求携带认证信息
|
||
});
|
||
|
||
// 预处理常见错误状态码
|
||
if (response.status === 401) {
|
||
// 未授权,可能是token过期
|
||
localStorage.removeItem('token');
|
||
localStorage.removeItem('user');
|
||
throw new Error('登录已过期,请重新登录');
|
||
}
|
||
|
||
let responseData;
|
||
try {
|
||
responseData = await response.json();
|
||
} catch (e) {
|
||
throw new Error('服务器响应格式错误');
|
||
}
|
||
|
||
if (!response.ok) {
|
||
// 提取错误详情
|
||
const errorMessage =
|
||
responseData.detail ||
|
||
responseData.message ||
|
||
responseData.error ||
|
||
`请求失败 (${response.status})`;
|
||
|
||
console.error('API错误:', {
|
||
status: response.status,
|
||
url,
|
||
error: errorMessage
|
||
});
|
||
|
||
throw new Error(errorMessage);
|
||
}
|
||
|
||
return responseData;
|
||
} catch (error) {
|
||
console.error('请求错误:', error);
|
||
throw error;
|
||
}
|
||
}
|