Fix: iOS SW-Update — SKIP_WAITING Handler, location.replace() statt reload(), no-store Header (SW by-v762)

This commit is contained in:
rene 2026-05-07 19:22:22 +02:00
parent a8b4fd781f
commit a3c8d77a14
4 changed files with 20 additions and 14 deletions

View file

@ -327,7 +327,7 @@ MEDIA_DIR = os.getenv("MEDIA_DIR", "/data/media")
os.makedirs(MEDIA_DIR, exist_ok=True)
app.mount("/media", StaticFiles(directory=MEDIA_DIR), name="media")
APP_VER = "761" # muss mit APP_VER in app.js übereinstimmen
APP_VER = "762" # muss mit APP_VER in app.js übereinstimmen
@app.get("/api/version")
async def app_version():
@ -848,7 +848,7 @@ async def share_target(request: Request):
# Weiterleitung zur App mit den Daten
return FileResponse(
f"{STATIC_DIR}/index.html",
headers={"Cache-Control": "no-cache"}
headers={"Cache-Control": "no-store, no-cache"}
)
# Öffentliche Hunde-Profilseite (für NFC-Tags, kein Login nötig)
@ -1182,17 +1182,17 @@ async def public_dog_page(dog_id: int):
# ------------------------------------------------------------------
@app.get("/teilen/{token}")
async def invite_page(token: str):
return FileResponse(f"{STATIC_DIR}/index.html", headers={"Cache-Control": "no-cache"})
return FileResponse(f"{STATIC_DIR}/index.html", headers={"Cache-Control": "no-store, no-cache"})
@app.get("/breeder/{zwingername}")
async def breeder_profile_page(zwingername: str):
return FileResponse(f"{STATIC_DIR}/index.html", headers={"Cache-Control": "no-cache"})
return FileResponse(f"{STATIC_DIR}/index.html", headers={"Cache-Control": "no-store, no-cache"})
@app.get("/litters")
async def litters_page():
return FileResponse(f"{STATIC_DIR}/index.html", headers={"Cache-Control": "no-cache"})
return FileResponse(f"{STATIC_DIR}/index.html", headers={"Cache-Control": "no-store, no-cache"})
# ------------------------------------------------------------------
@ -1200,7 +1200,7 @@ async def litters_page():
# ------------------------------------------------------------------
@app.get("/widget")
async def widget_page():
return FileResponse(f"{STATIC_DIR}/index.html", headers={"Cache-Control": "no-cache"})
return FileResponse(f"{STATIC_DIR}/index.html", headers={"Cache-Control": "no-store, no-cache"})
# ------------------------------------------------------------------
@ -1726,7 +1726,7 @@ async def partner_landing():
</div>
</body>
</html>"""
return HTMLResponse(content=html, headers={"Cache-Control": "no-cache"})
return HTMLResponse(content=html, headers={"Cache-Control": "no-store, no-cache"})
# ------------------------------------------------------------------
@ -1924,8 +1924,8 @@ async def spa_fallback(full_path: str):
'<link rel="apple-touch-icon" sizes="180x180" href="/icons/icon-180.png">',
'<link rel="apple-touch-icon" sizes="180x180" href="/icons/icon-180-staging.png">',
)
return HTMLResponse(content=html, headers={"Cache-Control": "no-cache"})
return HTMLResponse(content=html, headers={"Cache-Control": "no-store, no-cache"})
return FileResponse(
f"{STATIC_DIR}/index.html",
headers={"Cache-Control": "no-cache"}
headers={"Cache-Control": "no-store, no-cache"}
)

View file

@ -578,7 +578,7 @@
<script src="/js/api.js?v=94"></script>
<script src="/js/ui.js?v=94"></script>
<script src="/js/app.js?v=94"></script>
<script src="/js/worlds.js?v=761"></script>
<script src="/js/worlds.js?v=762"></script>
<!-- Feature-Seiten werden lazy geladen -->
@ -640,7 +640,8 @@
// Wenn neuer SW die Kontrolle übernimmt → Seite neu laden
navigator.serviceWorker.addEventListener('controllerchange', () => {
window.location.reload();
// location.replace statt reload() — bypassed iOS bfcache
window.location.replace(window.location.href);
});
navigator.serviceWorker.addEventListener('message', e => {

View file

@ -3,7 +3,7 @@
Router, State-Management, Navigation, Initialisierung.
============================================================ */
const APP_VER = '761'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
const APP_VER = '762'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
const APP_VERSION = '1.5.0'; // ← semantische Version, wird bei make release gesetzt
const IS_STAGING = location.hostname === 'staging.banyaro.app';
@ -1045,7 +1045,8 @@ const App = (() => {
const keys = await caches.keys();
await Promise.all(keys.map(k => caches.delete(k)));
} catch { /* ignorieren */ }
setTimeout(() => location.reload(), 600);
// location.replace bypassed iOS bfcache (reload() stellt alte Seite wieder her)
setTimeout(() => location.replace(location.href), 600);
});
}

View file

@ -3,7 +3,7 @@
Offline-Cache + Push Notifications + Tile-Cache
============================================================ */
const CACHE_VERSION = 'by-v761';
const CACHE_VERSION = 'by-v762';
const CACHE_STATIC = `${CACHE_VERSION}-static`;
const CACHE_TILES = 'ban-yaro-tiles-v1'; // bleibt über SW-Updates erhalten
const CACHE_API = 'ban-yaro-api-v1'; // API-Response-Cache
@ -344,6 +344,10 @@ self.addEventListener('sync', event => {
// MESSAGE — Tile-Vorausladung (Offline-Speicherung) + Queue-Steuerung
// ----------------------------------------------------------
self.addEventListener('message', event => {
if (event.data?.type === 'SKIP_WAITING') {
self.skipWaiting();
return;
}
if (event.data?.type === 'PROCESS_QUEUE') {
event.waitUntil(_processQueue());
return;