스파르타 spring 2기 TIL day3

fart man·2025년 11월 25일

Cache-Control

멘토님이 api 네트워크 트래픽을 공부하라고 하시길래 오늘은 http 헤더에 있는 모든 내용을 깊게 공부해보기로 하였다. 오늘안에 끝내고 실제 Response body내용도 볼 수 있을거라 생각했지만 깊게 파고들 수록 내가 얼마나 모르는지 더 알게되었다.

특히 Cache-Control부분에서 막혔다. 실제로 Cache가 어떻게 작동하는지 잘 몰랐기 때문이다 (그리고 아직도 사실 잘 모르겠다)

Cache

cache는http가 network 트래픽을 줄이기 위해 request를 받았을때 새요청을 주지 않고 옛날 요청을 재사용할 수 있게 해주는 메커니즘이다.

Cache는

  • 브라우저도 갖고 있고,
  • 서버도 갖고 있고,
  • 서버와 브라우저 중간에 있는 Proxy도 가지고 있다.

cache-diagram

브라우저가 가지고 있는 cache는 Private cache라고 하고 브라우저와 서버 중간, Proxy에 있는 cache를 Shared cache라고 한다.

브라우저 사용자 (javascript나 내가) 브라우저를 통해 요청을 할경우 저 위의 3중 누구라도 옛날 것을 재사용 할수 있다. 그 옛날 것을 조정하는 directive를 담고있는Header가 Cache-Control이다.

Cache-Control

Cache-Control의 구조는 다음과 같다.

Cache-Control : directive1=value, directive2=value, directive3, directive4=value...

그리고 각 Directive는Request와 Response가 같이 쓰는 것도 있고 따로 쓰는 것들도 있다.

Directives

Request, Response 공통

max-age=N
    Response : 이 응답은 N초뒤 상함
    Request : 생성된지 N초 넘은 응답은 상했으니까 주지마셈

no-cache
    Response : cache야 이 응답 cache된거 써도 되는데 그전에 나한테 validate해줘
    Request : Response와 동일

no-stroe
    Response : cache야 이 응답을 절대 저장하지마
    Request : cache야 서버한테서 온 응답을 절대 저장하지마

no-transfrom
    Response : cache야, 이미지 사이즈 줄이거나 그런 짓 하면 않돼
    Request : Response와 동일

stale-if-error
    Response : cache야, 서버쪽에서 에러 났으면 상한거 써도 돼
    Request : Response와 동일

Response 전용

s-maxage=N
    shared cache(CDN)에서 이응답은 N초 전까지 신선함, private cache(browser)는 무시

must-revalidate
    응답이 상하면 꼭 서버한테 다시 validate 할것.
    이 directive가 있는 이유는 http는 서버와 통신이 두절 됬을겨우 cache가 상한걸 serving하는걸 허용함.
    이 directive가 있을 경우 cache는 다시 validate를 하거나 504를 던져야 함.

proxy-revalidate
    must-revalidate랑 똑같은데 proxy(그나까 CDN)한테만 주는 directive

must-understand
    솔직히 저도 이건 뭔말인지 모르겠습니다 ㅠㅠ
    https://stackoverflow.com/questions/77318595/cache-control-i-dont-understand-must-understand

private
    이 응답은 private cache(브라우저)만 cache 할 수 있음

public
    이 응답은 shared cache(CDN)이 cache 할 수 있음
    Authorization header가 있어도 cache할 수 있음 (Authorizatio header는 또 뭣이여)

immutable
    cache야, 이 응답은 신선할 동안 절대 변하지 않을 거니까 신선할 동안은 validate할 필요가 없어 
    (근데 신선하다는게 그뜻 아닌가?)
    (검색해 보니까 브라우저는 신선해도 새로고침 하면 걍 서버한테 신선한지 물어본다네요https://engineering.fb.com/2017/01/26/web/this-browser-tweak-saved-60-of-requests-to-facebook/)

stale-while-revalidate=N
    cache야, 응답 상한거 써도 되는데 상한후에 N초안에 다시 validate 해줘. N초 전까지는 신선한척 하고 써도 돼
    (근데 이건 무슨 말인지 모르겠습니다. https://web.dev/articles/stale-while-revalidate)

Request 전용

max-stale=N
    N초 동안 상한건 괜찮아. N이 없을 경우 얼마나 상했는지 신경 안쓰겠다는 뜻

min-fresh=N
    생성된지 N초 이하인 것만 줘. 근데 이 다음 말은 무슨 말인지 모르겠습니다.
    https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cache-Control
    Clients can use this header when the user requires the response to not only be fresh, but also requires that it won't be updated for a period of time.

only-if-cached
    응답이 cache되었을 때만 줘

Validation

클라이언트는 자신이 저장하고 있는 응답이 상했을 경우 다시 가져와야 하는지 두가지 방법을 사용해 서버한테 물어본다.

첫번째 방법: If-Modified-Since

클라이언트가 서버 한테 '제가 알기론 이 콘텐츠가 2022년 7월 4일에 마지막에 수정 됬는데 혹시 또 나중에 수정이 또 됬나요?" 라고 물어본다.

GET /index.html HTTP/1.1
Host: example.com
Accept: text/html
If-Modified-Since: Tue, 4 July 2022 22:00:00 GMT

그럼 서버가 수정되지 않았다면 304 Not Modified 코드를 보내거나

HTTP/1.1 304 Not Modified
Content-Type: text/html
Date: Tue, 22 Feb 2005 23:22:22 GMT
Last-Modified: Tue, 4 July 2022 22:00:00 GMT
Cache-Control: max-age=3600

수정되었다면 update된 콘텐츠를 보내준다.

두번째 방법: ETag If-None-Match

근데 위에 방법은 넘 복잡하다. 그래서 Etag라는 방법이 새로 나왔다.

서버는 자신의 Response와 함께 Etag라는 것을 준다. ETag의 내용은 서버 맘대로 정할 수 있다.

그럼 클라언트는 상했을경우 자기가 받았던 ETag를 보내 '아직도 ETag이거 쓰나요?'라고 물어본다.

GET /index.html HTTP/1.1
Host: example.com
Accept: text/html
If-None-Match: "33a64df5"

그럼 서버는 클라이언트가 보낸ETag랑 자기가 현재 가지고 있는 콘텐츠의 ETag랑 비교해보고 똑같을 경우304를 던져준다.

아직도 모르겠엉

위 설명에 분명히 틀린 부분이 있을거 같다. 좀더 공부해야징.

0개의 댓글