네트워크

HTTP 웹 기본 지식 - HTTP 헤더(캐시와 조건부 요청)

SICDev 2021. 10. 19. 14:52
반응형

캐시 기본 동작❓

 

클라이언트가 서버에 star.jpg라는 이미지를 요청했을때❗

캐시가 없을때는 서버에서 Header와 요청에 맞는 Body를 클라이언트에게 보내줄 것이다. ( 너무 당연...😓 )

  • 데이터가 변경되지 않아도 요청시마다 네트워크를 통해 데이터를 받아야한다.
  • 인터넷 네트워크는 매우 느리고 비싸다.
  • 네트워크가 환경이 좋지 않거나 데이터가 방대하면 브라우저 로딩 속도가 느리게 느낄수 있다.

 

캐시를 적용하게되면 서버는 Header부분에 cache-control을 넣고 응답을 보내준다. ( 물론 서버에 캐시부분을 설정해줘야한다. )

그리고 캐시서버에 데이터를 저장한다👏

  • cache-control : max-age=60 -> 캐시가 유효한 시간(초) 를 의미한다.

클라이언트가 두번째 요청을 했을때 캐시에 값이 있는지 먼저 확인하고 값이 있으면 캐시에서 요청값을 가지고온다.

  • 데이터의 변경이 없으면 네트워크를 타지 않고 바로 캐시에서 데이터를 가져온다.
  • 캐시 덕분에 캐시 가능 시간동안 네트워크를 사용하지 않아도 된다.
  • 네트워크를 사용량을 줄일 수 있기 때문에, 네트워크 환경이 좋지 않아도 브라우저 로딩 속도가 빠르게 느낄수 있다.

 

캐시 시간이 초과되었다면 다시 서버에서 Header와 요청에 맞는 Body를 클라이언트에게 보내주고 이것을 캐시서버에 다시 저장한다.


캐시 검증 헤더와 조건부 요청❓

 

캐시 시간이 초과해서 서버에 다시 요청을했을때 두 가지의 상황이 있을수 있다.

  1. 서버에서 기존 데이터를 진짜 변경했을 때 EX) 별모양 이미지를 달모양으로 바꾸었다.
  2. 서버에서 기존 데이터를 변경하지 않았을 때

서버에서 기존 데이터를 변경했다면 다시 다운받는게 맞는데...데이터를 변경하지 않았다면❓🤔

굳이 또 데이터를 받을 필요가 있을까❓

 

이런 의구심을 해결하기위해 나온것이 캐시 검증 헤더와 조건부 요청이다.

 

데이터가 변경되지 않았다면 저장해 두었던 캐시를 재사용 할 수 있다.

재사용하기 위해 클라이언트의 데이터와 서버의 데이터가 동일하다는 검증이 필요기 때문에 바로 검증헤더가 나온것이다.

  • Last-Modified : Monday March 19, 12:00 UTC -> 이 데이터가 변경된 마지막 시간을 의미한다.

 

동작방식은 아래와 같다.

  1. 클라이언트의 첫 번째 요청에서 서버는 Last-modified 항목을 추가해서 데이터를 전송한다.
  2. 캐시 시간이 초과되었다는 가정하에 클라이언트가 두 번째 요청시에 캐시 데이터에 있던 Last-Modified 날짜를 If-Modified-Since라는 헤더에 추가해서 서버에게 보낸다.
  3. 서버는 클라이언트가 보낸 If-Modified-Since에 있는 날짜와 자신이 가지고 있는 데이터의 Last-Modified 날짜를 비교한다
  4. 날짜가 같다면 HTTP 응답을 만들때 304 Not Modified라는 응답을 보낸다. 이때 응답 데이터에는 HTTP Body가 없다. (왜❓ 수정된게 없기 때문에)
  5. 캐시 서버에 있는 데이터의 캐시 유효시간(cache-control)과 Last-modified(변경 시간)을 갱신하고 클라이언트는 캐시에서 데이터를 가져다 사용한다.

 

Last-Modified, If-Modified-Since를 사용할 때 몇가지 단점들이 있다.

  1. 1초 미만단위로는 캐시 조정이 불가능하다.
  2. 날짜 기반의 로직을 사용한다.
  3. 데이터를 수정해서 날짜는 다르지만, 결과가 같은 경우 EX) 수정했다가 다시 원복했을때
  4. 서버에서 별도의 캐시 로직을 관리하고 싶은 경우
    • 주석처럼 크게 영향이 없는 변경에서 캐시를 유지하고 싶은 경우

 

 

이런 단점들을 보완하기 위해 나온것이 ETag이다.

ETag는 캐시용 데이터에 임의의 고유한 버전을 설정한다❗❗

데이터가 변경되면 ETag값을 바꾸고, 데이터가 변경되지 않았으면 ETag값도 그대로 쓰면된다.

클라이언트는 단순하게 ETag값을 보내서 같으면 유지하고, 다르면 다시 받으면 된다❗

 

기존의 Last-Modified, If-Modified-Since을 사용했을때와의 방식을 동일하고

Last-Modified 대신 ETag를 사용하면되고, If-Modified-Since 대신 If-None-Match를 사용하면 된다👏

 


캐시 제어 헤더❓

 

Cache-Control ( 캐시 지시어 )

  • Cache-Control : max-age
    캐시 유효 시간을 나타낸다. ( 초 단위 )
  • Cache-Control : no-cache
    데이터를 캐시에 저장하여 사요해도 되지만, 항상 서버에 검증하고 사용해야한다.
  • Cache-Control : no-store
    케시에 저장하면 안된다.

 

Pragma ( 캐시 제어 )

  • Pragma : no-cache
    위의 Cache-Control : no-cache 처럼 동작하지만 요즘엔 쓰이지 않는다.

 

Expires ( 캐시 만료일 지정 )

  • expires : Mon, 01 Jan 1990 10:00:00 GMT
    캐시 만료일을 지정 날짜로 지정할 수 있다.
  • Cache-Control : max-age와 같이 사용할 시 expires는 무시된다

💡정리💡

검증헤더

  • ETag: "adefcfd"
  • Last-Modified: Thu, 04 Jun 2020 07:19:24 GMT

조건부 요청 헤더

  • If-None-Match, If-Match: ETag값 사용
  • If-Modified-Since, If-Unmodified-Since: Last-Modified값 사용
반응형