이 글은 모든 개발자를 위한 HTTP 웹 기본 지식 - 김영한님의 강의를 듣고 정리한 글입니다.
예시) 웹 브라우저에서 이미지(별)에 대한 요청
요청하였을 때의 이미지를 서버에서 응답해서 보내주고 응답해서 보내준 이미지를 브라우저 캐시에 저장하게 된다. (브라우저 내의 캐시 저장소에 저장)
다시 요청을 하게 될 경우 브라우저 내의 캐시 저장소를 뒤져서 확인하고 사용한다.
대신 서버가 응답해서 이미지를 보내줄 때, 제한을 걸어둘 수 있다.
캐시를 적용한 덕분에, 캐시 가능 시간동안 네트워크를 사용할 필요가 없다.
브라우저 로딩 속도가 빨라짐 (데이터를 다운로드 하지 않아도 되기 때문)
캐시 유효 시간이 초과되면, 서버를 통해 데이터를 다시 조회하고, 캐시를 갱신한다.
이때 다시 네트워크 다운로드가 발생한다.
다시 다운받은 정보를 캐시 저장소에 저장한다.
만약에 캐시 시간이 초과되었다고 해서 서버에 이미지를 다시 다운 받는데, 그 이미지가 캐시 안의 이미지와 똑같다면? -> 굳이 다운로드 받아야 할 필요가 있을까??
이때 검증 헤더 , 조건부 요청이 해결해준다.
헤더에 Last-Modified 를 넣어서 데이터가 마지막에 수정된 시간을 표기한다.
이렇게 될 경우 캐시 만료후에도 서버에 데이터를 변경하지 않았다면 다시 사용할 수 있어서 브라우저 캐시 안의 데이터를 불러서 사용할 수 있다.
하지만 Last-Modified가 수정되었다면 결국에 네트워크를 사용하여 이미지를 다운로드 받아야한다.
즉 정리하자면
캐시 유효 시간이 초과하여도 서버의 데이터가 갱신되지 않으면 서버는 304 Not Modified + 헤더 메타 정보만 응답한다.
클라이언트는 서버가 보낸 응답 헤더 정보로 캐시의 메타 정보를 갱신하고, 클라이언트는 캐시에 저장되어 있는 데이터를 재활용한다.
캐시 데이터와 서버 데이터가 같은지 검증하는 데이터
Last-Modified, ETage
검증 헤더로 조건에 따른 분기
If-Modified-Since: Last-Modified 사용
If-None-Match: ETag 사용
조건이 만족하면 200 OK
조건이 만족하지 않으면 304 Not Modified
1초 미만 단위로 캐시 조정이 불가능하다.
날짜 기반의 로직을 사용한다
데이터를 수정해서 날짜가 다르지만, 같은 데이터를 수정해서 데이터 결과가 똑같은 경우여도 다시 받아야한다.
이러한 단점을 해결해주는 것이 ETage이다.
ETage, If-None-Match
ETage(Entity Tag)
캐시용 데이터에 임의의 고유한 버전 이름을 달아둔다.
데이터가 변경되면 이 이름을 바꾸어서 변경한다 (Hash를 다시 생성한다)
단순하게 ETag만 보내서 같으면 유지, 다르면 다시 받을 수 있다.
그렇게 되면 캐시 제어 로직을 서버에서 완전히 관리할 수 있고
클라이언트는 단순히 이 값을 서버에 제공만 하면 된다.(클라이언트는 캐시 메커니즘을 모름)
예시)
서버는 배타 오픈 기간인 3일 동안 파일이 변경되어도 ETag를 동일하게 유지
애플리케이션 배포 주기에 맞추어 ETag 모두 갱신
Cache-Control : 캐시제어
Pragma : 캐시제어(하위호환)
Expires : 캐시 유효 기간(하위호환)
캐시 지시어(directives)
Cache-Control : max-age
Cache-Control : no-cache
Cache-Control : no-store
데이터에 민감한 정보가 있으므로 저장하면 안됨
메모리에서 사용하고 최대한 빠르게 삭제
캐시 제어(하위호환)
Pragma : no-cache
HTTP 1.0 하위 호환
캐시 만료일 지정(하위호환)
expires: Mon, 01 Jan 1990 00:00:00 GMT
캐시 만료일을 정확한 날짜로 지정한다.
HTTP 1.0 부터 사용
지금은 더 유연한 Cache-Control : max-age 권장
Cache-Control: max-age 와 함께 사용되면 expires는 무시된다.
ETag: "v1.0", ETag: "dawfew24"
Last-Modified: Thu, 04 Jun 2020 07:19:24 GMT
If-Match, If-None-Match: ETag 값 사용
If-Modified-Since, If-Unmodified-Since: Last-Modified 값 사용