fix(web): 生产环境忽略本机 API 地址

This commit is contained in:
Script Generator
2026-07-06 18:06:48 +08:00
parent a129edd9a4
commit 1b8c079c0d
2 changed files with 27 additions and 1 deletions

View File

@@ -12,6 +12,19 @@ test('API base defaults to same-origin in production and localhost in developmen
); );
}); });
test('API base ignores local-only absolute URLs in production', () => {
for (const localApiUrl of [
'http://localhost:3001/api/v1',
'http://127.0.0.1:3001/api/v1',
'http://0.0.0.0:3001/api/v1',
]) {
assert.equal(
resolveApiBase({ NODE_ENV: 'production', NEXT_PUBLIC_API_URL: localApiUrl }),
'/api/v1',
);
}
});
test('API requests use the resolved base path', async () => { test('API requests use the resolved base path', async () => {
const originalFetch = globalThis.fetch; const originalFetch = globalThis.fetch;
const apiBase = resolveApiBase(); const apiBase = resolveApiBase();

View File

@@ -5,11 +5,24 @@ type ApiEnv = {
export function resolveApiBase(env: ApiEnv = process.env) { export function resolveApiBase(env: ApiEnv = process.env) {
const fallback = env.NODE_ENV === 'production' ? '/api/v1' : 'http://localhost:3001/api/v1'; const fallback = env.NODE_ENV === 'production' ? '/api/v1' : 'http://localhost:3001/api/v1';
return (env.NEXT_PUBLIC_API_URL || fallback).replace(/\/$/, ''); const configured = (env.NEXT_PUBLIC_API_URL || fallback).replace(/\/$/, '');
if (env.NODE_ENV === 'production' && isLocalOnlyApiUrl(configured)) {
return '/api/v1';
}
return configured;
} }
const API_BASE = resolveApiBase(); const API_BASE = resolveApiBase();
function isLocalOnlyApiUrl(value: string) {
try {
const url = new URL(value);
return ['localhost', '127.0.0.1', '0.0.0.0'].includes(url.hostname);
} catch {
return false;
}
}
let apiAvailable: boolean | null = null; let apiAvailable: boolean | null = null;
let probePromise: Promise<boolean> | null = null; let probePromise: Promise<boolean> | null = null;