캐시의 데이터와 서버의 데이터가 같은지 검증하는 데이터.
검증 헤더에는 두가지가 있다.
☑️ Last-Modified
☑️ Etag
:
검증 헤더로 조건에 따라 분기한다.
☑️ If-Modified-Since
, If-UnModified-Since
: Last-Modified
사용
☑️ If-Match
, If-None-Match
: Etag
사용
☑️ 조건이 만족하면 : 200 OK
사용
☑️ 조건이 만족하지 않으면 : 304 Not Modified
사용
☑️ GMT 형식으로 시간을 입력한다.
☑️ 1초 미만의 단위로 캐시 조정이 불가능
☑️ 시간을 기반으로 로직을 사용한다.
예시) a를 b로 수정했다가 다시 a로 수정해도 데이터를 다운받아야한다.
☑️ 데이터가 수정되었을 시
캐시: 2020년 11월 10일 10:00:00 vs 서버: 2020년 11월 10일 11:00:00
서버에서 200 OK
그리고 HTTP Body
를 포함한 모든 데이터를 클라이언트에게 전송한다.
☑️ 데이터가 미수정되었을 시
캐시: 2020년 11월 10일 10:00:00 vs 서버: 2020년 11월 10일 10:00:00
서버에서 304 Not Modified
로 응답하여 캐시로 리다이렉션 하도록 하고 헤더 데이터만 전송(HTTP Body
미포함)한다.
캐시 제어 로직을 서버에서 완전 관리한다.
☑️ 캐시용 데이터에 임의의 고유한 이름을 만들어준다.
예시) ETag: "v1.0", ETag: "a2jiodwjekjl3"
☑️ 데이터가 변경되면 이 이름을 바꾸어서 변경한다.
예시) ETag: "aaaaa" -> ETag: "bbbbb"
정말 단순하게 클라이언트가 서버에 요청을 보낼때 Etag
만 보내서 데이터를 확인한다. Etag
가 같으면 캐시를 유지하고 Etag
가 다르면 데이터를 다시 다운받는다.
캐시의 유효시간이 초과해 서버에 데이터를 재요청해야 되는 상황이 발생했을 때 서버에 있는 데이터의 변경이 없다면 캐시에 있는 데이터를 그대로 사용해도 되는 상황이 발생한다.
이때 검증헤더와 조건부 요청을 이용하면 캐시에 있는 데이터를 그대로 사용할 수 있다.
캐시 유효시간이 초과해서 서버에 다시 요청하면 두가지 상황이 나타날 수 있다.
☑️ 서버에서 기존 데이터를 변경함. (🟡 -> 🟢)
☑️ 서버에서 기존 데이터를 변경하지 않음. (🟡)
위 두가지 상황중에서 서버에서 데이터를 변경하지 않아 캐시에 있는 유효시간이 초과된 데이터와 서버의 데이터가 같다면 다시 서버에 데이터를 재요청해 다운받는 과정은 네트워크 낭비일 수 있다.
이럴 경우 검증헤더와 조건부 요청을 사용해 기존의 캐시를 재활용할 수 있다.
서버에 데이터가 변경되지 않았다면 캐시에 있는 데이터와 서버에 있는 데이터가 동일하기 때문에 저장해두었던 캐시를 재활용하는것이 가능하다.
단, 이와같은 상황에서 클라이언트의 데이터와 서버의 데이터가 갔다는 것을 확인해줄 방법이 필요하다.
이럴 때 사용하는 것이 검증헤더이다.
첫 번째 데이터 요청에 대한 응답시 서버에서 데이터가 마지막에 수정된 시간을 헤더에 작성해 응답한다.
Last-Modified
는 데이터가 마지막에 수정된 시간을 나타낸다. 위 사진에서 시간을 나타내는 형식은 예시이기 때문에 실제 값을 나타내는 형식과는 다르다.
해당 값에 대한 시간은 GMT 형식으로 나타내야 한다.
(Last-Modified: Wed, 21 Oct 2015 07:28:00 GMT
)
웹 브라우저는 데이터 최종 수정일을 포함한 응답결과를 브라우저 캐시에 저장한다. 이때, 데이터 최종 수정일도 함께 저장한다.
이후 데이터 재요청시 캐시 유효시간이 초과 되었다면,
유효시간이 초과된 데이터의 최종 수정일을 요청의 if-modified-since
값에 담아 서버에 전송한다.
서버는 if-modified-since
값과 서버에 저장된 데이터의 최종 수정일을 비교한다.
만약, 데이터가 수정되지 않았다면
응답에 304 Not Modified
응답 결과와 Last-Modified
값을 담아 반환해준다.
이때 HTTP Body
는 전송하지 않는다. 응답메시지의 용량이 줄어들었기 때문에 네트워크 부하가 감소한다.
클라이언트는 해당 응답(304 Not Modified
)을 보고 데이터에 변경이 없다는 것을 확인하고 캐시를 갱신한다.
💡 정리하면,
캐시의 유효시간이 초과해도 서버의 데이터가 갱신되지 않았다면HTTP Body
없이304 Not Modified
+ 헤더정보 만을 반환한다.
클라이언트는 서버가 보낸 응답헤더 정보로 캐시의 정보를 갱신하고 갱신된 데이터를 재활용 한다.
데이터가 변경되지 않았을 경우 용량이 매우 적은 헤더 정보만을 다운로드하게 하는 매우 실용적인 방법이다.
실제 웹 브라우저는 Last-Modified
(검증헤더)와 If-Modified-Since
(조건부 요청)을 함께 사용하여 캐시가 갱신되는지 확인한다.
브라우저 네트워크창을 보면 색이 진한것과 연한것 두가지가 있는데 연한것은 캐시에서 불러온 데이터이다.
Status
와 Header
를 보면 304
응답코드와 if-modified-since
확인 가능하다.
첫 번째 요청에 대한 응답시 ETag
를 헤더에 담아서 보낸다.
웹 브라우저는 ETag
값을 브라우저 캐시에 저장한다.
캐시 유효시간이 초과되어 두번째 요청을 보낼 때 If-None_Match
에 ETag
값을 담아 보낸다.
데이터가 수정되지 않아 If-None_Match
조건을 만족하지 않는다.
서버는 HTTP Body
없이 304 Not Modified
로 응답하며 클라이언트는 해당 응답을 받아 캐시를 갱신한다.
클라이언트는 캐시를 재사용한다.
💡 정리하면,
단순하게ETag
만 비교해서 캐시 재사용 여부를 결정하며 캐시 제어 로직은 서버에서 완전히 관리한다.
클라이언트는 단순히 ETag값을 제공만할 뿐 캐시제어로직은 알지 못한다.
예1) 서버에서는 배타 오픈 기간인 3일동안 파일이 변경되어도 ETag를 유지한다.
예2) 애플리케이션 배포 주기에 맞춰 ETag를 갱신한다.
[Reference]
Catsbi's Dlog
김영한 - HTTP 웹 기본지식 강의
Mozilla
개발왕 도던