83 lines
2.2 KiB
TypeScript
83 lines
2.2 KiB
TypeScript
import axios, { AxiosRequestConfig, InternalAxiosRequestConfig } from 'axios';
|
||
import { getServerToken } from './server-auth';
|
||
|
||
type ResponseType<T = any> = {
|
||
code: number;
|
||
message: string;
|
||
data: T;
|
||
};
|
||
|
||
/**
|
||
* 服务端请求函数,用于 SSR
|
||
* 从 cookies 中获取 token 并添加到 Authorization header
|
||
* 如果接口不需要 token(如公开数据),token 会自动省略
|
||
*/
|
||
async function serverRequest<T = any>(
|
||
url: string,
|
||
config?: AxiosRequestConfig & {
|
||
requireAuth?: boolean; // 是否必须需要 token,默认 false(可选)
|
||
}
|
||
): Promise<ResponseType<T>> {
|
||
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<ResponseType<T>>(url, {
|
||
...requestConfig,
|
||
params: data,
|
||
});
|
||
|
||
return response.data;
|
||
}
|
||
|
||
/**
|
||
* 公开数据请求函数(不需要 token)
|
||
* 用于 SEO 友好的公开数据接口
|
||
*/
|
||
export async function publicServerRequest<T = any>(
|
||
url: string,
|
||
config?: AxiosRequestConfig
|
||
): Promise<ResponseType<T>> {
|
||
return serverRequest<T>(url, { ...config, requireAuth: false });
|
||
}
|
||
|
||
export default serverRequest;
|