import axios from 'axios'; import { ElMessage } from 'element-plus'; import { getBaseUrl } from './url.js'; // baseURL 由主进程动态分配端口,通过 getBaseUrl() 运行时获取 const axiosInstance = axios.create({ baseURL: getBaseUrl(), timeout: 300000, headers: { 'Content-Type': 'application/json;charset=utf-8', }, responseType: 'json', }); // 每次请求前动态更新 baseURL,确保服务启动后端口变更能被感知 axiosInstance.interceptors.request.use((config) => { config.baseURL = getBaseUrl(); return config; }); // 请求拦截 axiosInstance.interceptors.request.use((config) => { config.headers = config.headers || {}; let Authorization = localStorage.getItem('Authorization'); // 优先使用本地持久化的 Authorization 头(完整值) config.headers.Authorization = Authorization || ''; if ('get' === config?.method?.toLowerCase()) { if (config.params) { config.params.timestamp = new Date().getTime(); } } // 移除敏感信息日志 // console.log(config, 'axios request.use config') return config; }); axiosInstance.interceptors.response.use( (response) => { // 移除敏感信息日志 // console.log(response, 'response response') // 若请求为二进制下载(blob),直接透传响应,交由调用方自行处理 try { const isBlob = response?.config?.responseType === 'blob'; if (isBlob) { // 仍然尝试持久化可能返回的 Authorization const respHeaders = response?.headers || {}; const newAuthorization = respHeaders['authorization'] || respHeaders['Authorization']; if (newAuthorization && typeof newAuthorization === 'string') { localStorage.setItem('Authorization', newAuthorization); } return response; } } catch (e) { console.log(e); // 忽略检查失败 } // 如果响应头里带有 Authorization,则使用 useStorage 持久化到 localStorage, // 以便后续请求自动携带该请求头 try { const respHeaders = response?.headers || {}; const newAuthorization = respHeaders['authorization'] || respHeaders['Authorization']; if (newAuthorization && typeof newAuthorization === 'string') { localStorage.setItem('Authorization', newAuthorization); } } catch (e) { // 忽略持久化失败,避免影响主流程 console.warn('持久化 Authorization 失败:', e); } // 204 No Content(如 prompt_async)直接视为成功 if (response.status === 204) { return Promise.resolve(null); } if (response.status === 200) { const res = response.data || {}; const code = res.code; const msg = res.message || res.msg; // 明确的 200 成功,但需要按业务码再判断 if (code === 0) { // 业务成功 return Promise.resolve(res); } // 特殊业务码处理 if (code === 401) { // 清除持久化的 Authorization,避免后续使用失效的头部 localStorage.removeItem('Authorization'); sessionStorage.removeItem('Token'); // 延迟跳转,确保消息显示 setTimeout(() => { window.location.href = '/#/login'; }, 500); return Promise.reject(new Error('认证失败,请重新登录')); } // 其余非 0 的业务码统一拦截提示,但不在这里显示 ElMessage // 交由业务层使用 await-to-js 处理 return Promise.reject(new Error(msg || '请求失败')); } // 非 2xx 按错误分支处理(通常会进入 error 拦截器) return Promise.reject(new Error('请求失败')); }, (error) => { console.error('请求错误:', error); if (error.response) { // 服务器响应错误 const status = error.response.status; const message = error.response.data?.message || error.response.data?.msg || '请求失败'; switch (status) { case 400: ElMessage.error(`无效的请求参数:${message}`); break; case 401: // 清除持久化的 Authorization,避免后续使用失效的头部 localStorage.removeItem('Authorization'); ElMessage.error('未授权访问或登录已过期,请重新登录'); break; case 403: ElMessage.error('访问被拒绝'); break; case 404: ElMessage.error('资源未找到'); break; case 500: ElMessage.error('服务器内部错误'); break; case 502: case 503: case 504: ElMessage.error('服务暂时不可用,请稍后重试'); break; default: ElMessage.error(`请求失败: ${message}`); } } else if (error.request) { // 网络错误 ElMessage.error('网络连接失败,请检查网络连接'); } else { // 其他错误 ElMessage.error('请求发送失败'); } return Promise.reject(error); } ); export default axiosInstance;