From 6e5c29c73a9e0462bcebc39e541a537d35eb5bb4 Mon Sep 17 00:00:00 2001 From: Hyungi Ahn Date: Wed, 4 Mar 2026 14:05:34 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20Service=20Worker=20=EC=BA=90=EC=8B=9C=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EB=B0=8F=20auth-manager=20JSON.parse=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - sw.js: POST 요청 캐시 시도 차단 (Cache API는 GET만 지원) - sw.js: staleWhileRevalidate에서 response.clone() 타이밍 수정 (body 소비 전에 clone하도록 변경) - sw.js: 캐시 버전 v1.0.3으로 업데이트하여 구버전 캐시 강제 갱신 - auth-manager.js: 쿠키/localStorage에 "undefined" 문자열 저장된 경우 JSON.parse 오류 방지 Co-Authored-By: Claude Opus 4.6 --- .../web/static/js/core/auth-manager.js | 7 +++-- system3-nonconformance/web/sw.js | 28 +++++++++++-------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/system3-nonconformance/web/static/js/core/auth-manager.js b/system3-nonconformance/web/static/js/core/auth-manager.js index dbc93c5..aa72b69 100644 --- a/system3-nonconformance/web/static/js/core/auth-manager.js +++ b/system3-nonconformance/web/static/js/core/auth-manager.js @@ -65,11 +65,14 @@ class AuthManager { */ _getUser() { const ssoUser = this._cookieGet('sso_user') || localStorage.getItem('sso_user'); - if (ssoUser) { + if (ssoUser && ssoUser !== 'undefined' && ssoUser !== 'null') { try { return JSON.parse(ssoUser); } catch(e) {} } const userStr = localStorage.getItem('currentUser'); - return userStr ? JSON.parse(userStr) : null; + if (userStr && userStr !== 'undefined' && userStr !== 'null') { + try { return JSON.parse(userStr); } catch(e) {} + } + return null; } /** diff --git a/system3-nonconformance/web/sw.js b/system3-nonconformance/web/sw.js index e51942a..09b77ae 100644 --- a/system3-nonconformance/web/sw.js +++ b/system3-nonconformance/web/sw.js @@ -3,9 +3,9 @@ * M-Project 작업보고서 시스템 */ -const CACHE_NAME = 'mproject-v1.0.1'; -const STATIC_CACHE = 'mproject-static-v1.0.1'; -const DYNAMIC_CACHE = 'mproject-dynamic-v1.0.1'; +const CACHE_NAME = 'mproject-v1.0.3'; +const STATIC_CACHE = 'mproject-static-v1.0.3'; +const DYNAMIC_CACHE = 'mproject-dynamic-v1.0.3'; // 캐시할 정적 리소스 const STATIC_ASSETS = [ @@ -112,15 +112,20 @@ self.addEventListener('activate', (event) => { self.addEventListener('fetch', (event) => { const { request } = event; const url = new URL(request.url); - + + // POST 등 GET 이외 요청은 캐시 불가 → 기본 처리 + if (request.method !== 'GET') { + return; + } + // CORS 요청이나 외부 도메인은 기본 처리 if (url.origin !== location.origin && !isCDNResource(url)) { return; } - + // 캐시 전략 결정 const strategy = getCacheStrategy(request.url); - + event.respondWith( handleRequest(request, strategy) ); @@ -197,18 +202,19 @@ async function cacheFirst(request) { */ async function staleWhileRevalidate(request) { const cachedResponse = await caches.match(request); - + // 백그라운드에서 업데이트 const networkResponsePromise = fetch(request) - .then((networkResponse) => { + .then(async (networkResponse) => { if (networkResponse.ok) { - const cache = caches.open(DYNAMIC_CACHE); - cache.then(c => c.put(request, networkResponse.clone())); + const responseToCache = networkResponse.clone(); + const cache = await caches.open(DYNAMIC_CACHE); + cache.put(request, responseToCache); } return networkResponse; }) .catch(() => null); - + // 캐시된 응답이 있으면 즉시 반환, 없으면 네트워크 대기 return cachedResponse || await networkResponsePromise; }