From 9ae3cf2709a4d9c6c6c9b0c91ab266de3c783542 Mon Sep 17 00:00:00 2001 From: AWESOMEDEV Date: Fri, 17 Jul 2026 16:38:15 +0900 Subject: [PATCH] =?UTF-8?q?fix(cache):=20=EB=AC=B8=EC=84=9C=20iframe=20=3F?= =?UTF-8?q?v=3D=20=EC=BA=90=EC=8B=9C=EB=B2=84=EC=8A=A4=ED=84=B0=20+=20SPA?= =?UTF-8?q?=20=ED=91=9C=EC=A4=80=20=EC=BA=90=EC=8B=9C=20=EC=A0=95=EC=B1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 옛 X-Frame-Options:DENY 응답이 브라우저 캐시에 박혀 서버 수정 후에도 계속 '연결 거부'가 나던 문제의 근본 대응: - DocViewerPage iframe src에 ?v=2 — 캐시 키를 바꿔 새 응답을 받게(캐시 우회) - Caddy 캐시 정책 정리: /assets/*(해시파일) 영구 immutable, 그 외 HTML·문서 no-cache → 앞으로 헤더/내용 변경이 캐시에 눌어붙지 않고 즉시 반영 검증: 문서=no-cache+SAMEORIGIN, index=no-cache, assets=immutable. Co-Authored-By: Claude Opus 4.8 --- deploy/Caddyfile | 17 +++++++++++------ frontend/src/pages/DocViewerPage.jsx | 8 ++++++-- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/deploy/Caddyfile b/deploy/Caddyfile index e4bd5ed..379d969 100644 --- a/deploy/Caddyfile +++ b/deploy/Caddyfile @@ -35,12 +35,17 @@ edu.awesomedevapp.com { reverse_proxy backend:8080 } - # 학습 문서(HTML)는 캐시에 눌어붙지 않고 늘 서버에 재검증하게 한다. - # 학습 포인트: 예전에 실수로 X-Frame-Options:DENY가 붙은 문서가 브라우저에 캐시되면, - # 서버를 고쳐도 브라우저가 옛 응답을 재사용해 계속 막힌다("연결 거부"). no-cache는 - # "쓰기 전에 서버에 물어봐"라 헤더가 바뀌면 바로 반영된다. (문서는 작아서 비용도 작다.) - @docs path /docs/* - header @docs Cache-Control "no-cache" + # ── 캐시 정책 (SPA 표준) ── + # 학습 포인트: 무엇을 오래 캐시하고 무엇을 매번 확인할지 나눈다. + # 1) /assets/* — 빌드가 파일명에 해시를 박는다(index-A1B2.js). 내용이 바뀌면 이름이 + # 바뀌므로, 이 파일들은 "영원히" 캐시해도 안전하다(immutable) → 빠르다. + # 2) 그 외(HTML·학습 문서) — 항상 서버에 재검증(no-cache). 그래야 헤더나 내용이 바뀔 때 + # 즉시 반영된다. 예전에 잘못된 보안헤더가 문서 캐시에 눌어붙어 "연결 거부"가 났던 + # 그 문제를 원천 차단한다. (HTML은 작아 재검증 비용도 작다.) + @assets path /assets/* + header @assets Cache-Control "public, max-age=31536000, immutable" + @nocache not path /assets/* + header @nocache Cache-Control "no-cache" handle { root * /srv diff --git a/frontend/src/pages/DocViewerPage.jsx b/frontend/src/pages/DocViewerPage.jsx index cbcd244..ac50e55 100644 --- a/frontend/src/pages/DocViewerPage.jsx +++ b/frontend/src/pages/DocViewerPage.jsx @@ -53,9 +53,13 @@ export default function DocViewerPage() { {/* 학습 포인트: 기존 HTML 자산 재사용 — 학습 문서들은 이미 완성된 정적 HTML(public/docs/*.html)이다. React로 다시 만들 필요 없이 iframe으로 "액자에 넣듯" 보여주면 - 문서의 자체 스타일도 그대로 살고 앱 CSS와 충돌하지도 않는다. */} + 문서의 자체 스타일도 그대로 살고 앱 CSS와 충돌하지도 않는다. + ⚠️ ?v= 캐시 버스터: 예전에 잘못된 보안헤더(X-Frame-Options:DENY)가 붙은 문서가 + 브라우저 캐시에 박혀 새로고침으로도 안 지워지는 문제가 있었다. 주소 뒤에 버전을 + 붙이면 브라우저가 "다른 파일"로 보고 새로 받아온다(캐시 키가 달라짐). 헤더가 또 + 바뀌면 이 숫자만 올리면 된다. */}