이번 시간에는 캐시를 제어할 수 있는 검증 헤더와 이를 이용한 조건부 요청에 대해 알아보겠습니다.
만약 캐시 유효시간이 지났지만 변경이 없기 때문에 해당 데이터를 써도 되는 상황이라면 이를 검증하고 사용하는 방법은 없을까요?
검증 헤더 Last Modified를 이용해 캐시의 수정시간을 알 수 있습니다.
Last Modified는 데이터가 마지막으로 수정된 시간 정보를 헤더에 포함합니다.
이로 인해 응답 결과를 캐시에 저장할 때 데이터 최종 수정일도 저장됩니다.
응답 헤더의 Last-Modified에는 데이터 최종 수정일 정보가 담김
캐시 유효시간이 초과되더라도 If-Modified-Since 헤더를 이용해 조건부 요청을 할 수 있음
검증 헤더와 조건부 요청
Last-Modified와 If-Modified-Since
1. 데이터가 수정되었는지 검증
2. 수정되지 않았다면 바디를 제외한 HTTP 헤더만 전송
3. 브라우저 캐시에서 응답 결과를 재사용, 헤더 메타데이터 또한 갱신
4. 브라우저 캐시에서 조회한 데이터를 렌더링
서버의 해당 자료의 최종 수정일과 비교해서 데이터가 수정이 안되었을 경우 응답 메시지에 이를 담아서 알려줍니다.
이때 HTTP Body는 응답 데이터에 없으며 상태 코드는 304 Not Modified로 변경된 것이 없다는 뜻입니다.
그래서 전송 데이터에 바디가 빠졌기 때문에 헤더만 포함된 0.1M만 전송됩니다.
클라이언트에서는 해당 응답을 받은 뒤 캐시를 갱신해 주고 다시 일정 시간(60초) 동안 유효하게 됩니다.
Last-Modified와 If-Modified-Since
1. 장점
캐시 유효 시간이 초과해도, 서버의 데이터가 갱신되지 않으면?
304 Not Modified + 헤더 메타데이터만 응답 (바디X)
클라이언트는 서버가 보낸 응답 헤더 정보로 캐시의 메타데이터를 갱신
클라이언트는 캐시에 저장되어 있는 데이터 재활용
결과적으로 네트워크 다운로드가 발생하지만 용량이 적은 헤더 정보만 다운로드
매우 실용적인 해결책
ETag와 If-None-Match
ETag(Entity Tag)
캐시용 데이터에 임의의 고유한 버전 이름을 달아둠
데이터가 변경되면 이 이름을 바꾸어서 변경함 (Hash를 다시 생성)
단순하게 ETag만 보내서 같으면 유지, 다르면 다시 받는 방식
앞서 설명한 Last-Modified와 If-Modified-Since보다 좀 더 간단한 방식으로 ETag와 If-None-Match 검증 헤더가 있습니다.
서버에서 완전히 캐시를 컨트롤하고 싶은 경우 ETag를 사용할 수 있습니다.
ETab와 If-None-Match의 작동박식
서버에서 헤더에 ETag를 작성해 응답합니다.
클라이언트의 캐시에서 해당 ETag 값을 저장합니다.
캐시 유효 시간이 초과돼서 다시 요청을 해야 하는 경우라면 이때 ETag 값을 검증하는 If-None-Match를 요청 헤더에 작성해서 보낸다. (조건부 요청을 하는 것임)
ETag와 If-None-Match의 특징
1. 데이터가 수정되었는지 ETag를 이용해 검증
2. 수정되지 않았다면 바디를 제외한 HTTP 헤더만 전송
3. 브라우저 캐시에서 응답 결과를 재사용, 헤더 메타데이터 또한 갱신
4. 브라우저 캐시에서 조회한 데이터를 렌더링
서버에서 데이터가 변경되지 않았을 경우 ETag는 동일하기에 그래서 If-None-Match는 거짓이 됩니다.
이 경우 서버에서는 304 Not Modified를 응답하며 이때 역시 HTTP Body는 없습니다.
브라우저 캐시에서는 응답 결과를 재사용하고 헤더 데이터를 갱신합니다.
ETag와 If-None-Match 정리
단순하게 ETag만 보내서 같으면 유지, 다르면 다시 받는 방식
캐시 제어 로직을 서버에서 완전히 관리
클라이언트는 단순히 이 값을 서버에 제공 (클라이언트는 캐시 매커니즘을 모름)
e.g.
1. 서버는 베타 오픈 기간인 3일 동안 파일이 변경되어도 ETag를 동일하게 유지
2. 애플리케이션 배포 주기에 맞추어 ETag 갱신
캐시와 관련된 헤더들과 조건부 요청 헤더 정리
캐시 지시어(directives)
1. Cache-Control: max-age
캐시 유효 시간. 초단위
2. Cache-Control: no-cache
데이터는 캐시해도 되지만, 항상 원(Origin) 서버에 검증하고 사용
3. Cache-Control: no-store
데이터에 민감한 정보가 있으므로 저장하면 안됨
(메모리에서 사용하고 최대한 빨리 삭제)
Expires
캐시 만료일 지정(하위 호환)
Expires: Mon, 01 Jan 1990 00:00:00 GMT
캐시 만료일을 정확한 날짜로 지정
HTTP 1.0부터 사용
지금은 더 유연한 Cache-Control: max-age 권장
Cache-Control: max-age와 함께 사용하면 Expires는 무시됨
검증 헤더와 조건부 요청 헤더
정리
검증 헤더 (Validator)
ETag: "v1.0", ETag: "845eed07c5887cf"
Last-Modified: Wed, 26 Dec 2020 12:01:29 GMT
조건부 요청 헤더
If-Match, If-None-Match: ETag 값 사용
If-Modifed-Since, If-Unmodified-Since: Last-Modified 값 사용