Files
TK-FB-Project/web-ui/js/api-base.js
Hyungi Ahn 2b1c7bfb88 feat: 다수 기능 개선 - 순찰, 출근, 작업분석, 모바일 UI 등
- 순찰/점검 기능 개선 (zone-detail 페이지 추가)
- 출근/근태 시스템 개선 (연차 조회, 근무현황)
- 작업분석 대분류 그룹화 및 마이그레이션 스크립트
- 모바일 네비게이션 UI 추가
- NAS 배포 도구 및 문서 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 14:41:01 +09:00

105 lines
2.8 KiB
JavaScript

// /js/api-base.js
// API 기본 설정 및 보안 유틸리티 (비모듈 - 빠른 로딩용)
(function() {
'use strict';
// ==================== 보안 유틸리티 (XSS 방지) ====================
/**
* HTML 특수문자 이스케이프 (XSS 방지)
* innerHTML에 사용자 입력/API 데이터를 삽입할 때 반드시 사용
*
* @param {string} str - 이스케이프할 문자열
* @returns {string} 이스케이프된 문자열
*/
window.escapeHtml = function(str) {
if (str === null || str === undefined) return '';
if (typeof str !== 'string') str = String(str);
const htmlEntities = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#39;',
'/': '&#x2F;',
'`': '&#x60;',
'=': '&#x3D;'
};
return str.replace(/[&<>"'`=\/]/g, function(char) {
return htmlEntities[char];
});
};
/**
* URL 파라미터 이스케이프
*/
window.escapeUrl = function(str) {
if (str === null || str === undefined) return '';
return encodeURIComponent(String(str));
};
// ==================== API 설정 ====================
const API_PORT = 20005;
const API_PATH = '/api';
function getApiBaseUrl() {
const hostname = window.location.hostname;
const protocol = window.location.protocol;
// 프로덕션 환경 (technicalkorea.net 도메인)
if (hostname.includes('technicalkorea.net')) {
return `${protocol}//${hostname}${API_PATH}`;
}
// 개발 환경 (localhost 또는 IP)
return `${protocol}//${hostname}:${API_PORT}${API_PATH}`;
}
// 전역 API 설정
const apiUrl = getApiBaseUrl();
window.API_BASE_URL = apiUrl;
window.API = apiUrl; // 이전 호환성
// 인증 헤더 생성
window.getAuthHeaders = function() {
const token = localStorage.getItem('token');
return {
'Content-Type': 'application/json',
'Authorization': token ? `Bearer ${token}` : ''
};
};
// API 호출 헬퍼 (기존 시그니처 유지: endpoint, method, data)
// JSON 파싱하여 반환
window.apiCall = async function(endpoint, method = 'GET', data = null) {
const url = `${window.API_BASE_URL}${endpoint}`;
const config = {
method: method,
headers: window.getAuthHeaders()
};
if (data && (method === 'POST' || method === 'PUT' || method === 'PATCH' || method === 'DELETE')) {
config.body = JSON.stringify(data);
}
const response = await fetch(url, config);
// 401 Unauthorized 처리
if (response.status === 401) {
localStorage.removeItem('token');
localStorage.removeItem('user');
window.location.href = '/index.html';
throw new Error('인증이 만료되었습니다.');
}
// JSON 파싱하여 반환
return response.json();
};
console.log('✅ API 설정 완료:', window.API_BASE_URL);
})();