From 8fe2726c702489bc7551e3a0ced716559951f237 Mon Sep 17 00:00:00 2001 From: seo Date: Wed, 22 Jul 2026 01:06:29 +0900 Subject: [PATCH] =?UTF-8?q?=EC=97=90=EC=85=8B=20=EB=A6=AC=EB=A1=9C?= =?UTF-8?q?=EB=93=9C=20=EC=84=9C=EB=B9=84=EC=8A=A4=EC=9B=8C=EC=BB=A4=20?= =?UTF-8?q?=ED=95=B4=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- public/assets/asset-reload.js | 21 +++++++++++++-------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index e65136f..c6b6ae5 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ Control은 라즈베리파이/리눅스 호스트의 팬과 시스템 상태를 - `bin/wifi_observe.php`: 5G WiFi 연결 시간 보정을 위한 시스템단 관측 CLI - `systemd/control-wifi-observe.*`: WiFi 관측 CLI를 주기적으로 실행하는 systemd unit 예시 -`asset-version.php`는 `public`의 PHP/JS/CSS/manifest/icon 파일과 `config`의 PHP 파일을 읽어 크기, 수정 시각, sha256 hash를 묶은 버전을 만듭니다. `asset-reload.js`는 화면 복귀, 포커스 복귀, 온라인 복귀, 모바일 터치/클릭 복귀, 30초 간격으로 이 값을 다시 확인하고, 값이 달라지면 브라우저 Cache Storage를 비운 뒤 현재 화면을 다시 엽니다. 현재 URL의 `assetReload` 토큰이 최신 파일 묶음 hash와 다르면 첫 진입도 토큰을 붙인 URL로 다시 열어 낡은 JS/CSS가 먼저 실행되는 상황을 줄입니다. 삼성 브라우저 등에서 Web Storage나 `Promise.finally()` 호환성이 부족해도 동작하도록 쿠키 fallback과 timeout 기반 캐시 삭제를 사용합니다. `index.php`는 `no-store` 헤더를 내려 문서 자체가 브라우저 캐시에 오래 남지 않게 합니다. +`asset-version.php`는 `public`의 PHP/JS/CSS/manifest/icon 파일과 `config`의 PHP 파일을 읽어 크기, 수정 시각, sha256 hash를 묶은 버전을 만듭니다. `asset-reload.js`는 화면 복귀, 포커스 복귀, 온라인 복귀, 모바일 터치/클릭 복귀, 30초 간격으로 이 값을 다시 확인하고, 값이 달라지면 브라우저 Cache Storage를 비우고 service worker 등록을 해제한 뒤 현재 화면을 다시 엽니다. 현재 URL의 `assetReload` 토큰이 최신 파일 묶음 hash와 다르면 첫 진입도 토큰을 붙인 URL로 다시 열어 낡은 JS/CSS가 먼저 실행되는 상황을 줄입니다. 삼성 브라우저 등에서 Web Storage나 `Promise.finally()` 호환성이 부족해도 동작하도록 쿠키 fallback과 timeout 기반 캐시 삭제를 사용합니다. `index.php`는 `no-store` 헤더를 내려 문서 자체가 브라우저 캐시에 오래 남지 않게 합니다. ## 데이터/저장소 diff --git a/public/assets/asset-reload.js b/public/assets/asset-reload.js index 580fad1..694c770 100644 --- a/public/assets/asset-reload.js +++ b/public/assets/asset-reload.js @@ -155,6 +155,18 @@ }).catch(function () {}); } + function unregisterServiceWorkers() { + if (!navigator.serviceWorker || !navigator.serviceWorker.getRegistrations) return Promise.resolve(); + + return navigator.serviceWorker.getRegistrations().then(function (registrations) { + return Promise.all(registrations.map(function (registration) { + return registration.unregister().catch(function () {}); + })); + }).catch(function () {}); + } + + unregisterServiceWorkers(); + function reloadWith(version) { var token = version.slice(0, 12); var marker = token + ':' + Math.floor(Date.now() / 10000); @@ -163,14 +175,7 @@ if (assetTokenFromLocation() && sessionGet(reloadKey) === marker) return; sessionSet(reloadKey, marker); - withTimeout(deleteCaches(), 2500).then(function () { - if (navigator.serviceWorker && navigator.serviceWorker.getRegistrations) { - navigator.serviceWorker.getRegistrations().then(function (registrations) { - registrations.forEach(function (registration) { - if (registration && typeof registration.update === 'function') registration.update(); - }); - }).catch(function () {}); - } + withTimeout(Promise.all([deleteCaches(), unregisterServiceWorkers()]), 2500).then(function () { window.location.replace(addQuery(window.location.href, 'assetReload', token)); }); }