// api-config.js - nginx 프록시 대응 API 설정 function getApiBaseUrl() { const hostname = window.location.hostname; const protocol = window.location.protocol; const port = window.location.port; // 🔗 nginx 프록시를 통한 접근 (권장) // nginx가 /api/ 요청을 백엔드로 프록시하므로 포트 없이 접근 if (hostname.startsWith('192.168.') || hostname.startsWith('10.') || hostname.startsWith('172.') || hostname === 'localhost' || hostname === '127.0.0.1' || hostname.includes('.local') || hostname.includes('hyungi')) { // 현재 웹서버의 도메인/IP를 그대로 사용하되 /api 경로만 추가 const baseUrl = port && port !== '80' && port !== '443' ? `${protocol}//${hostname}:${port}/api` : `${protocol}//${hostname}/api`; return baseUrl; } // 🚨 백업: 직접 접근 (nginx 프록시 실패시에만) console.warn(' 직접 API 접근 (백업 모드)'); return `${protocol}//${hostname}:8000/api`; } export const API = getApiBaseUrl(); export function ensureAuthenticated() { const token = localStorage.getItem('sso_token'); if (!token || token === 'undefined') { alert('로그인이 필요합니다'); localStorage.removeItem('sso_token'); window.location.href = '/'; return null; } return token; } export function getAuthHeaders() { const token = localStorage.getItem('sso_token'); return { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }; } // 🔧 개선된 API 호출 함수 (에러 처리 강화) export async function apiCall(url, options = {}) { const defaultOptions = { headers: getAuthHeaders() }; const finalOptions = { ...defaultOptions, ...options, headers: { ...defaultOptions.headers, ...options.headers } }; try { const response = await fetch(url, finalOptions); // 인증 만료 처리 if (response.status === 401) { console.error(' 인증 만료'); localStorage.removeItem('sso_token'); alert('인증이 만료되었습니다. 다시 로그인해주세요.'); window.location.href = '/'; return; } // 응답 실패 처리 if (!response.ok) { let errorMessage = `HTTP ${response.status}`; try { const errorData = await response.json(); errorMessage = errorData.error || errorData.message || errorMessage; } catch (e) { // JSON 파싱 실패시 기본 메시지 사용 } throw new Error(errorMessage); } const result = await response.json(); return result; } catch (error) { console.error(` API 오류 (${url}):`, error); // 네트워크 오류 vs 서버 오류 구분 if (error.name === 'TypeError' && error.message.includes('fetch')) { throw new Error('네트워크 연결 오류입니다. 인터넷 연결을 확인해주세요.'); } throw error; } } // 디버깅 정보 hostname: window.location.hostname, protocol: window.location.protocol, port: window.location.port, href: window.location.href }); // 🧪 API 연결 테스트 함수 (개발용) export async function testApiConnection() { try { const response = await fetch(`${API}/health`, { method: 'GET', headers: { 'Content-Type': 'application/json' } }); if (response.ok) { return true; } else { return false; } } catch (error) { return false; } } // 개발 모드에서 자동 테스트 if (window.location.hostname === 'localhost' || window.location.hostname.startsWith('192.168.')) { setTimeout(() => { testApiConnection(); }, 1000); }