fix(web): API base 를 페이지 host 로 동적 해석 (LAN 접속 대응)
리뷰어 지적: docker-compose 가 NEXT_PUBLIC_API_BASE=http://localhost:8000 을 주입해서 클라이언트 번들에 localhost 가 inline 됨. 사금향 게임컴 (192.168.10.13) 브라우저에선 동작하지만, 같은 내부망의 다른 PC 또는 외부 검증자가 http://192.168.10.13:3000 에 접속하면 fetch 가 그 PC 의 localhost:8000 으로 가서 연결 실패. 백엔드는 정상인데도 '검색 결과 없음' 으로 보임. 해석 우선순위: 1) NEXT_PUBLIC_API_BASE 가 비 localhost 값 → 그대로 (프로덕션 도메인 케이스) 2) 브라우저 → window.location.hostname:8000 (LAN/localhost 자동 대응) 3) SSR 폴백 → localhost:8000 localhost/127.0.0.1 판별은 //(localhost|127.0.0.1)(?::|$) 정규식 — 'localhost.evil.com' 같은 서브도메인 우회는 매치 안 됨. node 로 7케이스 검증 완료. web/app 코드만이라 사금향 PC 는 restart.bat 으로 반영 (next dev hot-reload).
This commit is contained in:
@@ -1,8 +1,31 @@
|
||||
// Backend API client.
|
||||
// NEXT_PUBLIC_API_BASE 는 docker-compose 에서 http://localhost:8000 으로 주입됨.
|
||||
//
|
||||
// API 베이스 해석 우선순위:
|
||||
// 1) NEXT_PUBLIC_API_BASE 가 localhost/127.0.0.1 이 아닌 명시값 → 그대로 사용
|
||||
// (예: 프로덕션 https://api.example.com)
|
||||
// 2) 브라우저 환경 → window.location.hostname:8000 (LAN 접속도 자동 대응)
|
||||
// 3) SSR 폴백 → http://localhost:8000
|
||||
//
|
||||
// docker-compose 가 NEXT_PUBLIC_API_BASE=http://localhost:8000 을 주입하는 경우가 흔한데,
|
||||
// LAN 의 다른 PC 에서 http://<host>:3000 으로 접속하면 inline 된 localhost 가 그쪽 PC 의
|
||||
// localhost 를 가리켜 깨진다. 그래서 localhost/127.0.0.1 값은 신뢰하지 않고 페이지 host 로
|
||||
// 폴백.
|
||||
|
||||
const RAW_BASE = process.env.NEXT_PUBLIC_API_BASE ?? "http://localhost:8000";
|
||||
export const API_BASE = RAW_BASE.replace(/\/$/, "");
|
||||
function resolveApiBase(): string {
|
||||
const raw = process.env.NEXT_PUBLIC_API_BASE;
|
||||
const env = raw && raw.length > 0 ? raw.replace(/\/$/, "") : "";
|
||||
const envIsLocal = !env || /\/\/(localhost|127\.0\.0\.1)(?::|$)/.test(env);
|
||||
if (typeof window !== "undefined") {
|
||||
if (envIsLocal) {
|
||||
return `${window.location.protocol}//${window.location.hostname}:8000`;
|
||||
}
|
||||
return env;
|
||||
}
|
||||
// SSR
|
||||
return env || "http://localhost:8000";
|
||||
}
|
||||
|
||||
export const API_BASE = resolveApiBase();
|
||||
|
||||
export type Symbol = {
|
||||
code: string;
|
||||
|
||||
Reference in New Issue
Block a user