超管后台 - 调整所有的fetch 请求为后封装的 apiRequest,实现cookie 跨域

This commit is contained in:
柳清爽
2025-04-28 15:39:05 +08:00
parent 0eb629df70
commit 35341335d3
15 changed files with 459 additions and 475 deletions

View File

@@ -3,79 +3,78 @@ import { getConfig } from './config';
/**
* API响应接口
*/
export interface ApiResponse<T = any> {
interface ApiResponse {
code: number;
msg: string;
data: T | null;
data?: any;
}
/**
* API请求函数
* @param endpoint API端点
* @param method HTTP方法
* @param data 请求数据
* @param body 请求数据
* @param headers 请求头
* @returns API响应
*/
export async function apiRequest<T = any>(
export async function apiRequest(
endpoint: string,
method: 'GET' | 'POST' | 'PUT' | 'DELETE' = 'GET',
data?: any
): Promise<ApiResponse<T>> {
// 获取API基础URL
const { apiBaseUrl } = getConfig();
const url = `${apiBaseUrl}${endpoint}`;
method: string = 'GET',
body?: any,
headers: HeadersInit = {}
): Promise<ApiResponse> {
const url = `${process.env.NEXT_PUBLIC_API_BASE_URL}${endpoint}`;
// 构建请求头
const headers: HeadersInit = {
'Content-Type': 'application/json',
};
// 从localStorage获取token和admin_id
const token = typeof window !== 'undefined' ? localStorage.getItem('admin_token') : null;
const adminId = typeof window !== 'undefined' ? localStorage.getItem('admin_id') : null;
// 添加认证信息(如果有)
if (typeof window !== 'undefined') {
const token = localStorage.getItem('admin_token');
if (token) {
// 设置Cookie中的认证信息
document.cookie = `admin_token=${token}; path=/`;
}
// 设置cookie
if (typeof window !== 'undefined' && token && adminId) {
const domain = new URL(process.env.NEXT_PUBLIC_API_BASE_URL || '').hostname;
document.cookie = `admin_token=${token}; path=/; domain=${domain}`;
document.cookie = `admin_id=${adminId}; path=/; domain=${domain}`;
}
// 构建请求选项
const defaultHeaders = {
'Content-Type': 'application/json',
'Accept': 'application/json',
...headers
};
const options: RequestInit = {
method,
headers,
credentials: 'same-origin', // 改为same-origin避免跨域请求发送Cookie
headers: defaultHeaders,
credentials: 'include', // 允许跨域请求携带cookies
mode: 'cors', // 明确指定使用CORS模式
...(body && { body: JSON.stringify(body) })
};
// 添加请求体针对POST、PUT请求
if (method !== 'GET' && data) {
options.body = JSON.stringify(data);
}
try {
// 发送请求
const response = await fetch(url, options);
const data = await response.json();
// 解析响应
const result = await response.json();
// 如果响应状态码不是2xx或者接口返回的code不是200抛出错误
if (!response.ok || (result && result.code !== 200)) {
// 如果接口返回的code不是200抛出错误
if (data && data.code !== 200) {
// 如果是认证错误,清除登录信息
if (result.code === 401) {
if (data.code === 401) {
if (typeof window !== 'undefined') {
localStorage.removeItem('admin_id');
localStorage.removeItem('admin_name');
localStorage.removeItem('admin_account');
localStorage.removeItem('admin_token');
// 清除cookie
const domain = new URL(process.env.NEXT_PUBLIC_API_BASE_URL || '').hostname;
document.cookie = 'admin_token=; path=/; domain=' + domain + '; expires=Thu, 01 Jan 1970 00:00:00 GMT';
document.cookie = 'admin_id=; path=/; domain=' + domain + '; expires=Thu, 01 Jan 1970 00:00:00 GMT';
}
}
throw result; // 抛出响应结果作为错误
throw data; // 抛出响应结果作为错误
}
return result;
return data;
} catch (error) {
// 直接抛出错误,由调用方处理
console.error('API请求失败:', error);
throw error;
}
}