feat(client): 添加对authToken的处理 & 封装请求头

This commit is contained in:
dayjoy
2025-09-11 10:31:52 +08:00
parent 436b6f66a6
commit 01294f58b1
3 changed files with 134 additions and 2 deletions

View File

@@ -1,8 +1,14 @@
import "./App.css"; import "./App.css";
import React from "react"; import React, { useEffect } from "react";
import { Routes } from "react-router-dom"; import { Routes } from "react-router-dom";
import { handleAuthTokenFromUrl } from "./utils/auth";
const App: React.FC = () => { const App: React.FC = () => {
useEffect(() => {
// 在组件挂载时处理URL中的authToken
handleAuthTokenFromUrl();
}, []);
return ( return (
<div className="w-full h-full bg-gray-50"> <div className="w-full h-full bg-gray-50">
<main> <main>

View File

@@ -1 +1,79 @@
export default {}; import { getAuthToken } from '../utils/auth';
interface RequestOptions extends RequestInit {
headers?: Record<string, string>;
}
/**
* 统一的fetch请求封装
* 自动添加Authorization头部
*/
export const apiRequest = async <T = any>(
endpoint: string,
options: RequestOptions = {}
): Promise<T> => {
const authToken = getAuthToken();
const url = endpoint;
// 准备请求头
const headers: Record<string, string> = {
'Content-Type': 'application/json',
...options.headers,
};
// 如果有authToken添加Authorization头
if (authToken) {
headers.authorization = `Bearer ${authToken}`;
}
// 发起请求
const response = await fetch(url, {
...options,
headers,
});
// 处理响应
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
// 尝试解析JSON如果失败则返回响应对象
try {
return await response.json();
} catch {
return response as any;
}
};
// 便捷的HTTP方法封装
export const api = {
get: <T = any>(endpoint: string, options?: RequestOptions): Promise<T> =>
apiRequest<T>(endpoint, { ...options, method: 'GET' }),
post: <T = any>(endpoint: string, data?: any, options?: RequestOptions): Promise<T> =>
apiRequest<T>(endpoint, {
...options,
method: 'POST',
body: data ? JSON.stringify(data) : undefined,
}),
put: <T = any>(endpoint: string, data?: any, options?: RequestOptions): Promise<T> =>
apiRequest<T>(endpoint, {
...options,
method: 'PUT',
body: data ? JSON.stringify(data) : undefined,
}),
patch: <T = any>(endpoint: string, data?: any, options?: RequestOptions): Promise<T> =>
apiRequest<T>(endpoint, {
...options,
method: 'PATCH',
body: data ? JSON.stringify(data) : undefined,
}),
delete: <T = any>(endpoint: string, options?: RequestOptions): Promise<T> =>
apiRequest<T>(endpoint, { ...options, method: 'DELETE' }),
};
export default api;

View File

@@ -0,0 +1,48 @@
// 处理认证相关的工具函数
const AUTH_TOKEN_KEY = 'authToken';
/**
* 从URL搜索参数中获取authToken
*/
export const getAuthTokenFromUrl = (): string | null => {
const urlParams = new URLSearchParams(window.location.search);
return urlParams.get('authToken');
};
/**
* 保存authToken到localStorage
*/
export const saveAuthToken = (token: string): void => {
localStorage.setItem(AUTH_TOKEN_KEY, token);
};
/**
* 从localStorage获取authToken
*/
export const getAuthToken = (): string | null => {
return localStorage.getItem(AUTH_TOKEN_KEY);
};
/**
* 清除authToken
*/
export const clearAuthToken = (): void => {
localStorage.removeItem(AUTH_TOKEN_KEY);
};
/**
* 检查并处理URL中的authToken
* 如果URL中有authToken参数则保存到localStorage并从URL中移除
*/
export const handleAuthTokenFromUrl = (): void => {
const tokenFromUrl = getAuthTokenFromUrl();
if (tokenFromUrl) {
saveAuthToken(tokenFromUrl);
// 从URL中移除authToken参数
const url = new URL(window.location.href);
url.searchParams.delete('authToken');
window.history.replaceState({}, '', url.toString());
}
};