Cache Control

황유정·2025년 7월 13일

CS

목록 보기
2/3

Cache-Control : no-store

절대 캐시를 저장하지 않는다. 요청마다 무조건 서버에서 새로 받는다 (ex. 은행 로그인 페이지 등)

cache control 값이 no store기 때문에 저장하지 않고 새로고침시마다 파일을 계속 새롭게 다운 받는걸 확인할 수 있다

(+) 접속할 때 마다 웹 페이지를 바로 바로 가져오기 때문에 최신화 상태에는 유리하다
(-) 매번 가져와야 하기 때문에 사용자 입장에서 서비스가 느리다고 느낄 수 있다

Cache-Control : no-cache

캐시 저장은 가능하지만, 항상 서버에 재검증을 요청한다

기본 설정은 보통 no-cache로 해준다. 설정해주지 않으면 휴리스틱 캐싱(브라우저나 프록시 서버에서 임의로 캐싱을 하는 것)이 발생하여 의도치 않는 캐싱이 일어나 진짜 웹 서버에서 수정한 내역이 반영이 안될수도 있다

개인화된 정보가 있는 경우에는 private을 함께 붙여주는게 좋다

private을 붙이면 프록시 서버나 CDN 캐시에는 저장이 불가능하고 오직, 클라이언트 브라우저에만 저장된다

Cache-Control : maxAge

캐시 수명 설정 (초 단위)

최초 한 번만 다운받고 캐시가 살아있는 동안은 disk나 memory에서 데이터를 가져오기 때문에 속도가 빨라진다

(+) 유저 입장에서 서비스가 빠르다고 느낄 수 있다, 서버 측에서는 통신 비용을 줄일 수 있다

(-) 캐시가 살아있는 동안은 상태가 최신화 되지 않기 때문에 업데이트시 바로 반영할 수 없다

maxAge를 최대 기간인 1년으로 설정한 경우

maxAge를 5초로 설정한 경우

잘 살펴보면 최초로 다운 받은 용량은 3.1KB / 994KB인데, 5초 뒤에 다운 받은 용량은 191B / 192B다

왜 용량이 작아졌을까? ⇒ 서버에서 수정한 내용이 없기 때문이다

조건부 재검증

Last-Modified ↔ If-Modified-Since

  1. 최초의 브라우저 요청시 서버는 헤더에 파일을 마지막으로 수정한 시각인 Last-Modified를 실어 보낸다

  2. 재요청시 Request Headers에 서버에서 전달 받았던 마지막 수정된 버전의 날짜(If-Modified-Since)를 재요청때 헤더에 실어서 보낸다

  3. 서버는 이 날짜를 받아서 수정된 시간과 최신 시간이 일치하는지 확인하고, 변경사항이 없다면 (브라우저의 캐시가 최신 버전이라면) Status Code로 304 Not Modified를 보내며, 컨텐츠는 보내지 않고 통신을 완료한다 ⇒ 브라우저와 서버가 서로 헤더만 주고받지 큰 컨텐츠를 주고 받고있지는 않는다 (성능 향상)

  1. 서버에서 수정이 일어난다

  2. 브라우저에서 재요청을 보낸다

  3. Request Headers(브라우저)에 if-Modified-Since의 시각과 서버의 최신 버전의 시각이 다르기 때문에 서버에서는 Status Code 200 OK를 보내고 바뀐 내용을 Response Headers에 수정된 최신 시각(Last Modified)을 함께 실어 보낸다

ETag ↔ If-None-Match

서버는 초 단위의 수정 시각을 보낸다. 그러면 ms는 어떻게 처리하는가?

  1. 최초 요청이 발생해 서버로부터 헤더가 포함된 컨텐츠를 다운 받는다
    헤더에서는 ETag가 존재한다

  2. 브라우저가 두 번째 요청을 한다

    Request Headers에 이전에 서버로부터 받았던 ETag를 If-None-Match에 실어서 보낸다

  3. 서버는 현재 파일의 고유한 ETag가 브라우저측이 보낸 if-None-Match와 같은지 확인한다

    같다면, 변동 사항이 없으므로 Status Code : 304 Not Modified만 보낸다

  4. 다른 경우에는 Status Code : 200 Ok 와 데이터를 함께 보낸다

웹 서버는 Last-Modified와 ETag를 보내고, 재요청시 If-Modified-Since, If-None-Match 둘 중 하나라도 다르다면 컨텐츠를 보내준다


강제 재검증

Cache-Control : maxAge=0, must-revalidate 으로 설정한다면?

브라우저가 요청을 할 때마다 서버가 확인을 진행해서 수정됐을때만 실제로 다운로드가 진행되게 할 수 있다

마찬가지로 Cache-Control : no-cache로 설정해도 같은 기능을 한다

Cache-Control : no-cache

maxAge=0 설정처럼, 브라우저가 서버로 요청을 보낼때마다 수정된 시각을 확인하는 과정을 진행해서, 실제로 변동이 있을때만 다운로드가 진행되게끔 하는 방법이다


캐시 전략 가이드 (프론트엔드)

리소스전략
JS/CSS 번들Cache-Control: public, max-age=31536000, immutable + 파일명 해시
index.htmlno-cache
API 응답상황에 따라 ETag 또는 no-cache
로그인 후 페이지private, no-store

궁금한 부분

Q1. 캐시가 만료돼도 if-modified-since나 etag로 조건부 검증을 하여 컨텐츠의 변동여부를 확인해 최신화 시켜주는거라면, 캐시가 살아있을때는 어떻게 처리되는가?

A1. 재검증없이 브라우저 로컬 캐시에서 가져온 응답을 그대로 사용한다

Q2. 모든 웹 서버가 Etag와 if-modified-since를 모두 제공해주는가?

A2. 선택사항이다. 반드시 서버가 이를 제공해야 한다고 강제하지는 않는다


번외

Cache-Control 옵션

구분디렉티브설명
저장public응답이 모든 캐시(브라우저, 프록시 등)에 저장될 수 있음을 명시
저장private응답이 오직 개인 브라우저 캐시에만 저장되도록 함 (민감한 정보에 사용)
저장no-store절대 캐시 저장 금지. 요청마다 무조건 서버에서 새로 받아야 함 (ex. 은행 로그인 페이지)
저장no-cache캐시 저장은 가능하지만, 항상 서버에 재검증해야 함 (304 응답 가능)
저장only-if-cached서버와 통신하지 않고, 오직 캐시가 존재할 때만 응답 사용 (없으면 오류)
유효기간max-age=초응답이 최대 N초간 캐시 유효함 (예: max-age=3600)
유효기간s-maxage=초공용 캐시(CDN, 프록시 등)에서의 max-age (브라우저 캐시에는 영향 없음)
유효기간max-stale=초클라이언트가 만료된 캐시를 N초까지는 허용하겠다는 뜻
유효기간min-fresh=초캐시된 응답이 적어도 N초 이상 남아 있어야 사용 가능
재검증must-revalidate만료 후 반드시 서버에 검증해야 함 (만료되면 사용 불가)
재검증proxy-revalidate위와 같지만, 프록시 캐시에만 해당
재검증immutable응답이 절대 변하지 않음을 의미 (브라우저가 재검증을 하지 않음)

웹 저장 방식 비교

항목쿠키세션캐시LocalStorageSessionStorageIndexedDB
저장 위치클라이언트+ 서버 전송서버 (세션ID만 쿠키로 저장됨)브라우저 캐시 저장소클라이언트 (브라우저)클라이언트 (브라우저)클라이언트 (브라우저)
목적로그인 상태 유지 등사용자 상태 식별로그인 세션 등서버 상태 관리정적 리소스 최적화사용자 설정, 토큰 저장 등탭 단위 임시 저장구조화된 대용량 데이터 저장
서버 전송 여부✅ 전송됨 (자동)❌ 전송 안 함 (쿠키만 전송됨)
만료 시점설정 가능 (Max-Age, Expires)브라우저 종료 또는 타임아웃Cache-Control 등 설정삭제 전까지 영구 저장탭 닫을 때까지삭제 전까지 영구 저장
데이터 크기 제한약 4KB제한 없음 (서버 메모리 기반)수 MB 이상 가능보통 5~10MB보통 5~10MB수백 MB 이상
접근 방법JS에서 document.cookie서버 메모리에서 관리브라우저가 자동 처리JS에서 localStorageJS에서 sessionStorageJS에서 indexedDB API
보안 고려XSS, CSRF 주의HttpOnly, Secure, SameSite 권장세션 탈취 주의민감한 정보 저장 금지XSS 취약XSS 취약XSS 취약
브라우저 간 공유✅ (도메인 동일 시)❌ (탭 단위)✅ (도메인 동일 시)

자료 출처

생활코딩
https://www.youtube.com/watch?v=fczpUczepS4&list=PLuHgQVnccGMAM6VAWEKtaUnvzePCxnUVo&index=1

참고 문헌

https://www.youtube.com/watch?v=UxNz_08oS4E
https://developer.mozilla.org/ko/docs/Web/HTTP/Reference/Headers/Cache-Control
https://web.dev/articles/http-cache?hl=ko
https://toss.tech/article/smart-web-service-cache

profile
just do it

0개의 댓글