fix(web): 生产环境忽略本机 API 地址
This commit is contained in:
@@ -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();
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user