HTML 캐시 설정 방법, Nginx·Apache 적용과 검증
- HTML 캐시 정책은 서버나 애플리케이션의 HTTP 응답 헤더에서 설정합니다.
no-cache는 저장 후 재검증을 요구하고,no-store는 캐시에 저장하지 않도록 지시합니다.- 내용 해시가 파일명에 반영된 정적 파일은 긴 캐시 기간을 설정할 수 있습니다.
HTML 캐시를 설정할 때는 문서의 <meta> 태그보다 서버가 보내는 HTTP 응답 헤더의 Cache-Control을 조정하세요. 배포 뒤에도 브라우저가 HTML의 최신 여부를 확인하게 하려면 Cache-Control: no-cache를 적용할 수 있습니다. 이 값은 저장을 금지하는 뜻이 아니라, 저장한 응답을 다시 사용하기 전에 검증하라는 의미입니다.
HTML 캐시 설정의 기본 원칙

캐시 금지와 재검증은 다릅니다
no-store는 캐시가 응답을 저장하지 않도록 지시합니다. 반면 no-cache는 응답을 저장할 수 있지만 재사용 전에 원 서버에 검증하도록 합니다. 변경이 잦은 HTML에는 재검증 방식이 유용합니다. 서버가 ETag(응답 버전을 식별하는 값)나 Last-Modified(마지막 수정 시각)를 제공하고 클라이언트가 조건부 요청을 보내면, 변경되지 않은 경우 서버가 본문 대신 304 응답을 돌려줄 수 있습니다.
HTML과 정적 파일은 정책을 나눕니다
HTML이 오래 캐시되면 이전 페이지가 남아 새 CSS나 JavaScript 파일을 가리키는 문제가 생길 수 있습니다. HTML은 재검증하도록 하고, 파일 내용이 바뀔 때 URL도 달라지는 해시 파일명(예: app.a81f3c.js)을 사용하는 CSS·JS·이미지는 장기 캐시하는 구성이 일반적입니다. immutable은 캐시 유효 기간 중 파일이 바뀌지 않는다는 의미이므로, 내용 해시가 파일명에 반영된 자원에 사용하는 편이 안전합니다.
기준: HTML은 짧게 캐시하거나 재검증하고, 파일명이 내용 변경을 반영하는 정적 자원은 장기 캐시합니다. 파일명이 그대로인 자원에 장기 캐시를 설정하면 배포한 변경 사항이 늦게 보일 수 있습니다.
서버에서 HTML 캐시 헤더 설정하기

Nginx 설정 예시
다음 예시는 URL 경로가 .html로 끝나는 응답에 재검증 정책을 설정합니다. 사이트의 루트 경로(/)나 애플리케이션 라우트는 이 정규식과 일치하지 않을 수 있으므로, 실제 요청을 처리하는 location에 맞춰 적용하세요.
location ~* \.html$ {
add_header Cache-Control "no-cache";
}
해시 파일명을 사용하는 정적 자원은 경로 규칙을 분리할 수 있습니다. 아래 예시는 URL 경로가 /assets/인 경우입니다.
location /assets/ {
add_header Cache-Control "public, max-age=31536000, immutable";
}
Nginx의 add_header는 현재 응답 코드와 설정 계층의 상속 규칙에 따라 적용됩니다. 하위 location에 별도의 add_header를 두면 상위 계층의 해당 지시어가 상속되지 않을 수 있으므로 기존 보안·기타 응답 헤더도 확인하세요. 설정 문법을 검사한 뒤 다시 불러오고, 실제 배포 주소에서 헤더를 확인합니다. 프록시 구조라면 요청이 어느 서버 블록과 경로 규칙을 통과하는지도 살펴보세요.
Apache 설정 예시
Apache에서 mod_headers가 활성화되어 있다면 가상 호스트 설정 또는 허용된 .htaccess에 파일 이름별 응답 헤더를 지정할 수 있습니다. 다음 예시는 이름이 .html로 끝나는 파일에 적용됩니다.
<FilesMatch "\.html$">
Header set Cache-Control "no-cache"
</FilesMatch>
실제 서버가 이 설정을 읽는지 확인하세요. 호스팅 환경에 따라 .htaccess 사용이 제한되거나 헤더 모듈이 비활성화되어 있을 수 있습니다. 루트 경로나 애플리케이션이 생성하는 응답은 실제 처리 방식에 맞춰 별도로 설정해야 할 수 있습니다.
HTML meta 태그만으로 설정하면 안 되는 이유

<meta http-equiv="Cache-Control" content="no-cache">는 서버가 보내는 HTTP 응답 헤더를 바꾸지 못하며, 중간 캐시의 정책도 제어하지 못합니다. 이 태그를 읽는 시점에는 브라우저가 이미 HTML 응답을 받은 뒤이므로, 배포 환경에 캐시 정책을 적용하려면 웹 서버나 애플리케이션 응답에서 Cache-Control을 설정하세요. MDN의 HTTP 캐싱 안내와 MDN의 http-equiv 안내에서 관련 동작을 확인할 수 있습니다.
적용하고 확인하는 4단계

1단계: 어떤 응답을 바꿀지 정합니다
HTML 문서, 이미지, CSS·JS 중 캐시 정책을 바꿀 대상을 구분합니다. HTML 전체에 재검증을 적용할지, 로그인 등 일부 경로에 저장 제한을 적용할지 결정하고 정적 파일의 URL에 내용 해시가 반영되는지 확인하세요.
2단계: 서버 응답에 정책을 설정합니다
Nginx나 Apache 설정, 또는 애플리케이션의 응답 헤더에서 Cache-Control을 지정합니다. 민감한 정보가 포함된 페이지는 no-store와 접근 통제를 검토하고, 일반적인 HTML 최신성 문제에는 no-cache를 고려하세요.
3단계: 실제 응답 헤더를 확인합니다
배포된 주소에 다음 명령을 실행합니다. -D -는 응답 헤더를 출력하고 -o /dev/null은 본문을 버립니다.
curl -sS -D - -o /dev/null https://example.com/
결과에서 Cache-Control, ETag, Last-Modified를 확인하세요. curl -I는 HEAD 요청이므로 GET 응답과 설정이 다를 수 있습니다. CDN을 쓴다면 원본 서버와 CDN 경유 주소를 각각 확인합니다.
4단계: 브라우저에서 재검증과 배포를 살핍니다
개발자 도구의 Network 탭에서 문서 응답 헤더와 상태 코드를 확인합니다. 저장된 응답을 재검증했을 때 내용이 바뀌지 않았다면 304가 올 수 있고, 변경됐다면 새 응답을 받아야 합니다. 서비스 워커나 CDN이 별도 캐시를 운영한다면 브라우저 HTTP 캐시와 구분해 점검하세요. 헤더 변경만으로 사용자 기기에 이미 저장된 응답이 모두 즉시 삭제되지는 않습니다.
상황별 Cache-Control 선택

| 대상·상황 | 예시 정책 | 기대 동작 |
|---|---|---|
| 일반 HTML | no-cache |
저장은 허용하고 재사용 전에 검증 |
| 민감한 응답의 저장 제한 | no-store |
캐시에 저장하지 않도록 지시 |
| 해시가 포함된 정적 파일 | public, max-age=31536000, immutable |
유효 기간 동안 장기 재사용 |
| 사용자별 응답 | private, no-cache |
공유 캐시 저장을 제한하고 재사용 전에 검증 |
max-age는 응답을 신선한 것으로 취급하는 기간을 초 단위로 지정합니다. private는 공유 캐시가 응답을 저장하지 못하게 하지만 브라우저 같은 개인 캐시의 저장까지 막지는 않으며, 인증이나 접근 제어를 대신하지 않습니다. 사용자별 응답을 캐시에 저장하지 않게 해야 하는지, 아예 저장하지 않게 해야 하는지는 응답의 민감도와 배포 방식을 고려해 정하세요. 실제로 전달되는 최종 응답 헤더도 확인해야 합니다.
설정이 안 먹을 때 확인할 항목

- 응답 헤더에 규칙이 없는 경우: 설정 문법 오류, 비활성 모듈, 잘못된 가상 호스트·경로를 확인합니다.
- 원본은 바뀌었지만 브라우저가 이전 화면을 표시하는 경우: HTML의 캐시 헤더와 정적 파일 URL이 함께 갱신됐는지 확인합니다.
- 서버 헤더와 브라우저 결과가 다른 경우: CDN, 리버스 프록시, 서비스 워커가 응답을 바꾸거나 별도로 캐시하는지 살펴봅니다.
- 헤더 수정 후에도 이전 내용이 남는 경우: 서버 설정 변경만으로 사용자 브라우저에 저장된 응답이 일괄 삭제되지는 않습니다. CDN 캐시 무효화나 파일 URL 변경이 필요한지 검토합니다.
주의:
no-cache는 “캐시하지 말라”가 아니라 “사용 전에 검증하라”는 뜻입니다. 저장 자체를 제한하려는 민감한 응답에는 용도에 맞는 정책을 별도로 선택하세요.
자주 묻는 질문
Q. HTML에 meta 태그를 넣으면 캐시 설정이 끝나나요?
아닙니다. meta 태그는 서버가 보내는 HTTP 응답 헤더를 바꾸지 못하며 중간 캐시 정책도 제어하지 못합니다. 서버나 애플리케이션 응답에서 Cache-Control을 설정하세요.
Q. no-cache와 no-store 중 무엇을 써야 하나요?
최신 여부를 확인하면서 저장된 응답을 재사용하려면 no-cache를 고려합니다. 응답을 캐시에 저장하지 않도록 제한해야 하는 민감한 화면에는 no-store를 검토하세요.
Q. 모든 HTML에 no-store를 적용해도 되나요?
적용할 수는 있지만 요청마다 본문을 다시 받아야 할 수 있어 전송량과 응답 시간이 늘어날 수 있습니다. 일반 페이지는 재검증 정책을 검토하고, 민감한 내용이 있는 응답은 별도로 판단하세요.
Q. 설정했는데 배포 후에도 옛 화면이 보이는 이유는 무엇인가요?
브라우저에 이미 저장된 응답, CDN·프록시, 서비스 워커, 변경되지 않은 정적 파일 URL 등이 원인일 수 있습니다. curl로 실제 응답 헤더를 확인하고 각 캐시 계층과 파일 버전을 순서대로 점검하세요.
