본문 바로가기
  • 시 쓰는 개발자
CS 개념/네트워크

HTTP 웹 기본 지식 (8) - HTTP 헤더 2 (完)

by poetDeveloper 2024. 5. 16.

김영한님의 HTTP 웹 기본지식을 들으며 정리하였습니다.

 

캐시

  • 캐시 기준 : 자주 사용되지만 잘 안바뀌는 것들.(로고나 버튼같은 이미지, CSS, JS 등) 물론, 개발자가 선정하기 나름임.
  • 캐시가 없다면 이미지같은 것들을 다운로드 받을 때 같은 이미지를 두번 세번 내려받기 때문에 비효율적이고 로딩 속도도 느려진다.

캐시 vs 쿠키 맥락차이

  • 캐시 : 클라이언트 자체에서(웹브라우저) 이미지 등을 로컬에 저장해두었다가 사용자가 같은 요청을 보낼 때 로딩을 더 효율적으로 하기 위함.
  • 쿠키 : 서버가 필요해서 클라이언트에 저장하는 데이터이다. 사용자가 사이트에 재방문할 때, 사용자의 사이트 설정, 로그인 상태 유지 등을 가능하게 해주는 식별 역할을 한다.
  • 정리) 캐시는 성능 최적화를 위해 이미지자료 등을 저장함. 사용자 식별과는 관련 없는 데이터 저장. ↔ 쿠키는 사용자의 세션관리, 개인화, 광고 등을 위한 트래킹 등에 활용되듯이 개인정보와 관련된 내용 포함함.

검증 헤더 1 (Last-Modified  ,  if-Modified-Since)

클라이언트가 가지고 있는 데이터와, 서버가 가지고 있는 데이터가 같다는 것을 검증해주는 데이터이다.

▶ 캐시 시간이 만료되면 서버에서 이미지를 다시 다운로드 해야한다. 근데 같은 이미지 파일이라면?? 캐시가 만료됐다 하더라도 똑같은 이미지를 다시 캐시하는게 비효율적이다. 이럴 땐 검증 헤더를 사용한다.

  • Last-Modified : 이걸 헤더에 추가해서 데이터의 최종 수정일을 명시해준다. 그리고 캐시할 때 이 정보까지 같이 캐시한다.
  • if-modified-since : 캐시 만료 후 다시 요청을 보내는데, 이때 이 헤더를 보내준다. 즉, 클라이언트가 가지고 있는 파일의 최종 수정일은 이때인데, 서버가 가지고 있는 건 언제니 ?
  • 304 Not Modified : 위에 둘을 비교해보고 만약 같다면, 즉 데이터가 수정되지 않았다면 서버에서 데이터를 다시 보내줄 필요가 없음. 그니까 캐시된거 그대로 쓰라고 알려줌. 이때 HTTP Body를 전송하지 않고 헤더만 전송해서 데이터를 많이 아낄 수 있음. (서버가 응답을 보내긴 하지만, 헤더만 보내기에 매우 적은 양을 보내는 것이라 실용적임)
  • 200 OK : if-modified-since를 보냈는데, 어 수정됐어 라고 대답하면서 새로운 파일 보내주는 거임. 바로 위에서는 "수정됐니?" 라고 물어봤는데 "아니 수정안됐으니까 네가 가지고 있는 캐시 써"라고 하는게 304인거고, "어 맞아 수정됐어 다시 보내줄게" 하는게 200인거임.
  • 단점 : 1초 미만은 캐시 조정 불가능, A → B → A 해서 사실은 같은 파일이지만 수정 날짜는 달라져서 데이터 결과가 같은 걸 다시 캐시하는 걸 막지 못함.

 

구글에서 아무거나 검색하고, F12에서 이미지 파일 하나를 클릭해보았다. 그리고 그때 새로고침을 했으면, 이미지 파일을 다시 요청한 셈이니 위 사진처럼 304 Status를 보내준다. 그리고 저걸 클릭해보면 다음과같이 304 Not Modified라고 되어 있는 것을 볼 수 있고, if modified since도 확인할 수 있었다.

 

이미지 파일에서 확인한 if-modified-since
이미지파일에서 확인한 304 not modified

 

즉, 이미지파일을 로컬에서 캐시된 상태로 들고있다가 새로고침 하니까 요청 보내서 서버에서 데이터 수정 여부를 확인하고, 수정되지 않은 파일이라 로컬에 있는 이미지를 다시 불러온 것이다.

검증 헤더 2 (ETag  ,  if-None-Match)

  • ETag (Entity Tag) : 캐시용 데이터에 임의의 고유한 버전 이름을 달아두고, 데이터가 변경되면 이 값을 바꾸는 방법임(HASH값 다시 생성). 단순하게 ETag를 비교해서 같으면 유지, 다르면 다시 요청함. 검증헤더1 에서 이야기하는 단점을 고치고자 하는데 바로 ETag임.
    • 캐시 제어 로직을 서버에서 관리하게 됨.
    • 클아이언트는 단순히 ETag값을 서버에 제공할 뿐, 로직을 알 수 없음.

캐시 제어 헤더

  • Cache-Control ★ : 캐시 제어 (지금은 이거로 다 커버 가능해서 이걸 씀)
    • max-age : 캐시 유효시간, 초 단위임. (초단위로 유연하게 설정 가능)
    • no-cache : 캐시 해도 되는데, 항상 origin 서버에 검증하고 캐시써라. 즉, 확인받고 조건부 저장
    • no-store : 민감한 정보는 저장하면 안됨.
    • public : 응답을 public 캐시에 저장해도 됨
    • private : 응답을 해당 클라이언트를 위해서만 사용함. (프록시 서버에 저장 불가)
  • Pragma : 캐시 제어
    • no-cache
    • HTTP 1.0 하위호환이라 지금은 거의 안씀.
  • Expires : 캐시 유효 기간
    • 캐시 만료일을 저장. 하지만 Cache-Control의 max-age랑 같이 쓰이면 Expires는 무시됨.
    • HTTP 1.0부터 사용

Proxy Cache  ,  Origin Server

  • Origin 서버 : 실제 데이터가 저장된 서버를 의미. 근데 여기서 모든 걸 관리하며 여기저기 데이터 뿌려주면 멀기도 하고 비효율적임. 그래서 클라이언트와 origin 사이에 "proxy 캐시 서버"를 둠.(ex. 구글쓸 때 미국과 한국 오가기는 어려우니까 한국 어딘가에 프록시 서버를 두고 사용)

캐시 무효화

캐시 요청 안해도, 웹브라우저가 임의로 캐시하기도 함. 그런걸 확실하게 방지하기 위해 캐시를 무효화 하는 응답이 있음. 아래 내용들을 다 넣어주면 거의 대부분 막을 수 있다고 함.

  • Cache-Control: no-cache, no-store, must-revalidate
    • no-cache : 캐시 해도 되는데, 항상 origin 서버에 검증하고 캐시써라. 만약 origin 서버가 잠깐 에러나서 접근 못하면 예전 데이터라도 보내줄 수 있음.
    • no-store : 민감한 정보 있으니까 저장하지 마세요.
    • must-revalidate : 캐시 만료 후 최초 조회시, origin 서버에 검증해야함. no-cache와는 달리, origin 에러나서 접근 못하는 상황이면 무조건 오류(504)가 발생함.
  • Pragma: no-cache
    • 혹시 과거 브라우저가 있을 수 있으니까 그런것도 막아주기 위함임.