[HTTP] 헤더 - 캐시와 조건부 동작

Local Gaji·2024년 1월 3일

🎈 캐시

데이터가 변경되지 않았는데 똑같은 요청이 올 때마다 똑같은 데이터를 전송하면 비효율적이다. 헤더에서 캐시 정보를 명시해서 캐시를 사용하도록 할 수 있다.

cache-control: max-age=60  // 캐시가 유효한 시간 (s)

캐시 헤더가 있으면 브라우저는 해당 데이터를 저장했다가 캐시 시간이 만료되기 전까지 캐시된 데이터를 사용한다. 캐시가 만료된 이후 데이터가 필요하면 다시 요청을 보내 응답 데이터를 얻는다.


🎈 조건부 요청

캐시가 만료되어 다시 서버에 요청을 했을 때, 데이터가 기존 캐싱된 데이터와 여전히 같을 수도 있다. 데이터가 변경되지 않았다면 데이터를 다시 다운로드 하는 것보다 캐시를 그대로 쓰는게 더 효율적이다.

이런 방법을 사용하기 위해서는 서버의 데이터가 캐시랑 다른지 같은지 검증하는 과정이 필요한데, 헤더에 데이터 변경 시간을 명시해서 검증할 수 있다.

Cache-control: max-age=60
Last-Modified: 데이터가 마지막으로 수정된 시간 (UTC)

데이터

브라우저에 캐시 저장 시 최종 수정 시간 정보를 함께 저장한다. 그리고 캐시가 만료되어 새로운 요청을 보낼 때 이 시간 정보를 헤더에 명시한다.

GET /start.jpg
if-modified-since: 브라우저 캐시가 가지고있는 최종 수정 시간 (UTC)

서버는 현재 데이터가 이 일자 이후에 수정되었는지 아닌지 확인한다. 만약 해당 일자 이후에 데이터가 수정되지 않았으면 (신선하면) 서버는 304 Not Modified 응답을 보낸다. 이 응답에는 ResponseBody (실제 데이터)가 포함되지 않는다.


🎈 ETag

검증 헤더인 Last-Modified, if-modified-since 조합으로 조건부를 요청할 때, 만약 수정을 했는데 데이터가 여전히 똑같을 수도 있다. 서버에서 캐시 로직을 완전히 관리하고 싶다면 ETag 라는 태그를 사용해서 버전을 명시한다. 캐시 데이터가 만료되도록 하고싶다면 ETag 이름을 변경한다.

Get /star.jpg
if-None-Match: "1"  // ETag

if-None-Match 헤더 값과 ETag가 다르다면 데이터를 다시 보낸다. ETag 가 같으면 304 응답만 보낸다.


🎈 캐시 제어 헤더

  • 캐시 지시 헤더 : Cache-Control
    • max-age=만료시간(초) : 유효기간 지정
    • no-cache : 데이터를 캐싱하되 쓸때마다 origin서버에 조건부 요청을 매번 하라는 뜻
    • no-store : 데이터를 캐싱하지 말라는 뜻
  • 캐시 만료일 지정 헤더 : Expires
    • 잘 안씀, Cache-Control 과 함께 사용하면 무시됨
  • 검증 헤더
    • ETag (버전 기준)
    • Last-Modified (최종 수정 시간 기준)
  • 조건부 요청 헤더
    • If-Match, If-None-Match (ETag 기준)
    • If-Modified-Since, If-Unmodified-Since (최종 수정 시간 기준)

🎈 프록시 캐시

origin 서버는 거리가 멀어서 전송 시간이 많이 걸릴 수 있다. 브라우저가 프록시 캐시 서버로 접근하면 캐싱된 데이터를 가져오게 된다. 캐시 서버에 저장된 캐시는 public 캐시, 브라우저에 저장된 캐시는 private 캐시이다.

  • 캐시 지시 헤더 : Cache-Control
    • public, private (기본값)
    • s-maxage : 프록시 서버에만 적용되는 캐시 만료 기간
    • Age : 프록시 서버에 캐시가 머문 시간

🎈 캐시 무효화

웹 브라우저가 임의로 캐시를 할수도 있으므로 확실히 캐시를 무효화 하려면 아래 정보를 헤더에 모두 명시해야 한다.

Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache (과거 브라우저 대처)

no-cache 옵션만 있으면 origin 서버에 접근 실패 시 프록시 서버에서 캐싱된 데이터를 보내줄 수 있지만, must-revalidate 옵션이 포함되면 origin 서버 접근 실패 시 에러가 발생한다.

0개의 댓글