fix: 前端 API 调用改为相对路径,通过 Vite 代理避免 CORS

前端 5 个文件中硬编码了 http://localhost:8080 绝对路径,
浏览器从 127.0.0.1:5173 访问时触发 CORS 预检失败。
改为相对路径 /api/v1/... 通过 Vite 代理转发,
WebSocket URL 改为动态构造(基于当前页面 host)。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-22 21:51:56 +08:00
parent 8bbde1c1d7
commit 7c3b428257
5 changed files with 12 additions and 9 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
import type { AuthResponse } from '@/types/session';
const API_BASE_URL = import.meta.env.VITE_API_URL || 'http://localhost:8080/api/v1';
const API_BASE_URL = import.meta.env.VITE_API_URL || '/api/v1';
/** localStorage key 前缀 */
const LS_TOKEN_KEY = 'token';
+1 -1
View File
@@ -38,7 +38,7 @@ interface FileResponse {
thumbnail_url?: string;
}
const API_BASE = import.meta.env.VITE_API_URL || 'http://localhost:8080/api/v1';
const API_BASE = import.meta.env.VITE_API_URL || '/api/v1';
/**
* 获取带授权头的文件下载/缩略图 URL (用于 fetch 直接获取 blob)
+1 -1
View File
@@ -170,7 +170,7 @@ export async function exportSession(
): Promise<void> {
const token = localStorage.getItem('token');
const resp = await fetch(
`${import.meta.env.VITE_API_URL || 'http://localhost:8080/api/v1'}/sessions/${encodeURIComponent(sessionId)}/export?format=${format}`,
`${import.meta.env.VITE_API_URL || '/api/v1'}/sessions/${encodeURIComponent(sessionId)}/export?format=${format}`,
{
headers: {
Authorization: `Bearer ${token}`,
+2 -2
View File
@@ -73,7 +73,7 @@ async function transcribeAudio(audioBlob: Blob, language?: string): Promise<ApiR
// 不设置 Content-Type,让浏览器自动处理 multipart boundary
try {
const response = await fetch('http://localhost:8080/api/v1/voice/transcribe', {
const response = await fetch('/api/v1/voice/transcribe', {
method: 'POST',
headers,
body: formData,
@@ -110,7 +110,7 @@ async function synthesizeSpeech(req: TTSSynthesizeRequest): Promise<string> {
headers['Authorization'] = `Bearer ${token}`;
}
const response = await fetch('http://localhost:8080/api/v1/voice/tts', {
const response = await fetch('/api/v1/voice/tts', {
method: 'POST',
headers,
body: JSON.stringify(req),
+7 -4
View File
@@ -5,8 +5,11 @@ import { useNotificationStore } from '@/store/notificationStore';
import { getToken } from '@/api/client';
import type { Message, WSClientMessage, WSServerMessage } from '@/types/chat';
const WS_BASE_URL =
import.meta.env.VITE_WS_URL || 'ws://localhost:8080/ws/chat';
function getWsUrl(): string {
if (import.meta.env.VITE_WS_URL) return import.meta.env.VITE_WS_URL;
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
return `${protocol}//${window.location.host}/ws/chat`;
}
// ========== 指数退避重连配置 ==========
const INITIAL_RECONNECT_DELAY_MS = 1000; // 初始延迟 1 秒
@@ -77,8 +80,8 @@ export function useWebSocket() {
const sessionID = useSessionStore.getState().currentSessionId || '';
const url = sessionID
? `${WS_BASE_URL}?token=${token}&session_id=${sessionID}`
: `${WS_BASE_URL}?token=${token}`;
? `${getWsUrl()}?token=${token}&session_id=${sessionID}`
: `${getWsUrl()}?token=${token}`;
console.log(`[WS#${instanceId}] 正在连接, session_id=${sessionID || '(无)'}, reconnectAttempt=${reconnectCountRef.current}`);
const ws = new WebSocket(url);