import axios from 'axios'; // 1. 创建 axios 实例 const api = axios.create({ // 根据你的环境变量或硬编码地址 baseURL: process.env.NEXT_PUBLIC_API_URL || 'http://45.137.220.138:8888', headers: { 'Content-Type': 'application/json', }, }); // 2. 请求拦截器:自动携带 Token api.interceptors.request.use( (config) => { // 仅在客户端执行时获取 token if (typeof window !== 'undefined') { const token = localStorage.getItem('rsid'); if (token) { config.headers.Authorization = `Bearer ${token}`; } } return config; }, (error) => { return Promise.reject(error); } ); // 3. 响应拦截器:全局处理 401 自动跳转 api.interceptors.response.use( (response) => { // 请求成功,直接返回 return response; }, (error) => { // 检查响应是否存在,且状态码是否为 401 if (error.response && error.response.status === 401) { console.warn('Session expired or unauthorized (401). Cleaning up...'); // 确保在浏览器端执行 if (typeof window !== 'undefined') { // A. 清除本地存储的 Token 和用户信息 localStorage.removeItem('rsid'); localStorage.removeItem('user_info'); // B. 触发 storage 事件,通知 Navbar 等组件更新状态 (变为未登录) window.dispatchEvent(new Event('storage')); // C. 强制跳转到登录页 // 增加判断:如果当前已经在 /login 页面,就不需要跳转了,防止登录失败时死循环刷新 if (!window.location.pathname.startsWith('/login')) { // 使用 window.location.href 强制跳转,确保页面状态彻底重置 // 也可以使用 router.push('/login'),但 axios 外部拿不到 router 实例,href 最通用 window.location.href = '/login'; } } } // 继续抛出错误,以便组件内具体的 try/catch 也能捕获(比如显示"用户名密码错误") return Promise.reject(error); } ); export default api;