[네트워크] | HTTP 헤더 - 검증헤더와 조건부 요청

제롬·2022년 5월 10일
0
post-custom-banner

✅ 검증 헤더

캐시의 데이터와 서버의 데이터가 같은지 검증하는 데이터.

검증 헤더에는 두가지가 있다.

☑️ Last-Modified
☑️ Etag :

✅ 조건부 요청 헤더

검증 헤더로 조건에 따라 분기한다.

☑️ If-Modified-Since, If-UnModified-Since : Last-Modified 사용
☑️ If-Match, If-None-Match : Etag 사용
☑️ 조건이 만족하면 : 200 OK 사용
☑️ 조건이 만족하지 않으면 : 304 Not Modified 사용

✅ If-Modified-Since와 Last-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(Entity tag)와 If-None-Match

캐시 제어 로직을 서버에서 완전 관리한다.

☑️ 캐시용 데이터에 임의의 고유한 이름을 만들어준다.
예시) ETag: "v1.0", ETag: "a2jiodwjekjl3"

☑️ 데이터가 변경되면 이 이름을 바꾸어서 변경한다.
예시) ETag: "aaaaa" -> ETag: "bbbbb"

정말 단순하게 클라이언트가 서버에 요청을 보낼때 Etag만 보내서 데이터를 확인한다. Etag가 같으면 캐시를 유지하고 Etag가 다르면 데이터를 다시 다운받는다.

✅ 검증헤더와 조건부 요청의 사용

캐시의 유효시간이 초과해 서버에 데이터를 재요청해야 되는 상황이 발생했을 때 서버에 있는 데이터의 변경이 없다면 캐시에 있는 데이터를 그대로 사용해도 되는 상황이 발생한다.
이때 검증헤더와 조건부 요청을 이용하면 캐시에 있는 데이터를 그대로 사용할 수 있다.

캐시 유효시간이 초과해서 서버에 다시 요청하면 두가지 상황이 나타날 수 있다.

☑️ 서버에서 기존 데이터를 변경함. (🟡 -> 🟢)
☑️ 서버에서 기존 데이터를 변경하지 않음. (🟡)

위 두가지 상황중에서 서버에서 데이터를 변경하지 않아 캐시에 있는 유효시간이 초과된 데이터와 서버의 데이터가 같다면 다시 서버에 데이터를 재요청해 다운받는 과정은 네트워크 낭비일 수 있다.

이럴 경우 검증헤더와 조건부 요청을 사용해 기존의 캐시를 재활용할 수 있다.

✅ Last Modified를 사용한 검증헤더와 조건부 요청

서버에 데이터가 변경되지 않았다면 캐시에 있는 데이터와 서버에 있는 데이터가 동일하기 때문에 저장해두었던 캐시를 재활용하는것이 가능하다.

단, 이와같은 상황에서 클라이언트의 데이터와 서버의 데이터가 갔다는 것을 확인해줄 방법이 필요하다.

이럴 때 사용하는 것이 검증헤더이다.

첫 번째 데이터 요청에 대한 응답시 서버에서 데이터가 마지막에 수정된 시간을 헤더에 작성해 응답한다.

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(조건부 요청)을 함께 사용하여 캐시가 갱신되는지 확인한다.

브라우저 네트워크창을 보면 색이 진한것과 연한것 두가지가 있는데 연한것은 캐시에서 불러온 데이터이다.

StatusHeader를 보면 304 응답코드와 if-modified-since 확인 가능하다.


✅ Etag(Entity tag)를 사용한 검증헤더와 조건부요청

첫 번째 요청에 대한 응답시 ETag를 헤더에 담아서 보낸다.

웹 브라우저는 ETag 값을 브라우저 캐시에 저장한다.

캐시 유효시간이 초과되어 두번째 요청을 보낼 때 If-None_MatchETag값을 담아 보낸다.

데이터가 수정되지 않아 If-None_Match 조건을 만족하지 않는다.

서버는 HTTP Body 없이 304 Not Modified로 응답하며 클라이언트는 해당 응답을 받아 캐시를 갱신한다.

클라이언트는 캐시를 재사용한다.

💡 정리하면,
단순하게 ETag만 비교해서 캐시 재사용 여부를 결정하며 캐시 제어 로직은 서버에서 완전히 관리한다.
클라이언트는 단순히 ETag값을 제공만할 뿐 캐시제어로직은 알지 못한다.
예1) 서버에서는 배타 오픈 기간인 3일동안 파일이 변경되어도 ETag를 유지한다.
예2) 애플리케이션 배포 주기에 맞춰 ETag를 갱신한다.


[Reference]
Catsbi's Dlog
김영한 - HTTP 웹 기본지식 강의
Mozilla
개발왕 도던

post-custom-banner

0개의 댓글