Files
electron-opencode/src/renderer/http/index.js
2026-04-11 16:54:09 +08:00

152 lines
5.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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;