import axios, { AxiosRequestConfig, InternalAxiosRequestConfig } from 'axios'; import { getServerToken } from './server-auth'; type ResponseType = { code: number; message: string; data: T; }; /** * 服务端请求函数,用于 SSR * 从 cookies 中获取 token 并添加到 Authorization header * 如果接口不需要 token(如公开数据),token 会自动省略 */ async function serverRequest( url: string, config?: AxiosRequestConfig & { requireAuth?: boolean; // 是否必须需要 token,默认 false(可选) } ): Promise> { const { requireAuth = false, ...requestConfig } = config || {}; // 从 cookies 中获取 token const token = await getServerToken(); // 如果需要 token 但没有 token,可以选择抛出错误或继续请求 // 这里选择继续请求,让后端决定是否允许访问 if (requireAuth && !token) { throw new Error('Authentication required'); } // 创建 axios 实例 const instance = axios.create({ withCredentials: false, baseURL: 'http://54.223.196.180:8091', validateStatus: (status) => { return status >= 200 && status < 500; }, }); // 设置请求拦截器,添加 token 到 Authorization header // 与客户端 request.ts 保持一致 // 注意:token 是可选的,用于 SEO 的公开数据可以不带 token instance.interceptors.request.use((config: InternalAxiosRequestConfig) => { if (token) { config.headers.setAuthorization(`Bearer ${token}`); } return config; }); // 处理参数 let data: any; if (requestConfig && requestConfig?.params) { const { params } = requestConfig; data = Object.fromEntries( Object.entries(params).filter(([, value]) => value !== '') ); } console.log('url', url); // 发起请求 const response = await instance>(url, { ...requestConfig, params: data, }); return response.data; } /** * 公开数据请求函数(不需要 token) * 用于 SEO 友好的公开数据接口 */ export async function publicServerRequest( url: string, config?: AxiosRequestConfig ): Promise> { return serverRequest(url, { ...config, requireAuth: false }); } export default serverRequest;