HTTP 헤더는 클라이언트와 서버 간 메타데이터를 전달하는 키-값 쌍이다. 캐싱, 보안, 콘텐츠 협상, CORS 등 웹의 핵심 메커니즘이 헤더를 통해 제어된다.
캐싱 헤더
Cache-Control 지시자:
max-age=N : N초 동안 캐시 유효
s-maxage=N : 공유 캐시(CDN)에서 N초 유효
no-cache : 매번 서버에 재검증 (ETag/Last-Modified)
no-store : 캐시하지 않음 (민감한 데이터)
must-revalidate: 만료 후 반드시 재검증
immutable : 절대 변경되지 않음 (버전화된 자산)
stale-while-revalidate=N: 만료 후 N초까지 stale 응답 허용
public : 공유 캐시 허용
private : 브라우저 캐시만 허용
ETag: "abc123" → 리소스 버전 식별자
Last-Modified: Thu, 01 Jan 2026 00:00:00 GMT
재검증 요청:
If-None-Match: "abc123" → ETag 일치 시 304 Not Modified
If-Modified-Since: [날짜] → 변경 없으면 304
캐싱 전략 예시
nginx
# Nginx 설정
# HTML: 캐시 안 함 (항상 최신)
location ~* .html$ {
add_header Cache-Control "no-cache";
add_header ETag $request_id;
}
# 버전화 자산: 영구 캐시
location ~* .(js|css|woff2)$ {
# 파일명에 해시 포함 시 (app.abc123.js)
add_header Cache-Control "public, max-age=31536000, immutable";
}
# API 응답: 짧은 캐시
location /api/ {
add_header Cache-Control "public, max-age=60, stale-while-revalidate=30";
add_header Vary "Accept-Encoding, Accept-Language";
}
Vary 헤더
http
# Vary: 어떤 요청 헤더에 따라 응답이 달라지는지 CDN에 알림
Vary: Accept-Encoding # gzip vs br vs identity 별도 캐시
Vary: Accept-Language # 언어별 다른 응답
Vary: Accept # JSON vs HTML 다른 응답
# 잘못된 사용: Vary: Cookie 는 캐시 효과 없음
중요 보안/기타 헤더
http
# 콘텐츠 타입 스니핑 방지
X-Content-Type-Options: nosniff
# 클릭재킹 방지
X-Frame-Options: DENY
# 참조자 정책
Referrer-Policy: strict-origin-when-cross-origin
# 권한 정책 (Permissions Policy)
Permissions-Policy: camera=(), microphone=(), geolocation=(self)
# 서버 식별 제거 (보안)
Server: (제거 또는 최소화)
관련 문서