[HTTP] ETag ์ํฐํฐ ํ๊ทธ ํค๋
TL;DR
ETag(์ํฐํฐ ํ๊ทธ; Entity Tag)๋ HTTP ์๋ต ํค๋ ์ค ํ๋๋ก, ์น ๋ฆฌ์์ค์ ํน์ ๋ฒ์ ์ ์๋ณํ๊ธฐ ์ํ ๊ณ ์ ํ ์๋ณ์๋ค. ํด๋ผ์ด์ธํธ๋ ETag๋ฅผ ์ด์ฉํด ๋ฆฌ์์ค ๋ณ๊ฒฝ ์ฌ๋ถ๋ฅผ ์๋ฒ์ ๊ฒ์ฆํ๊ณ , ๋ณ๊ฒฝ๋์ง ์์์ผ๋ฉด ์บ์ ๋ ์ฝํ ์ธ ๋ฅผ ์ฌ์ฌ์ฉํจ์ผ๋ก์จ ๋์ญํญ์ ์ ์ฝํ๊ณ ์ฑ๋ฅ์ ๊ฐ์ ํ ์ ์๋ค.
์๋ ๋ฐฉ์
- ํด๋ผ์ด์ธํธ๊ฐ ํน์ ๋ฆฌ์์ค๋ฅผ ์ฒ์ ์์ฒญํ๋ฉด, ์๋ฒ๋ ์๋ต ํค๋์ ETag ๊ฐ์ ํฌํจํ์ฌ ๋ฆฌ์์ค์ ํจ๊ป ์ ๋ฌ
- ํด๋ผ์ด์ธํธ๋ ์๋ต์ผ๋ก ๋ฐ์ ETag ๊ฐ ์ ์ฅ
- ์ดํ ๋์ผํ ๋ฆฌ์์ค ์ฌ์์ฒญ ์
If-None-Match
์์ฒญ ํค๋์ ETag ๊ฐ์ ๋ด์์ ์๋ฒ๋ก ์ ์ก - ์๋ฒ๋ ์ ๋ฌ๋ฐ์ ETag ๊ฐ๊ณผ ํ์ฌ ๋ฆฌ์์ค์ ETag ๊ฐ ๋น๊ต
- ๊ฐ์ด ์ผ์นํ๋ฉด ๋ณธ๋ฌธ(body)์ ์๋ตํ๊ณ
304 Not Modified
๋ฐํ - ๊ฐ์ด ์ผ์นํ์ง ์์ผ๋ฉด ์ต์ ๋ฆฌ์์ค์ ์๋ก์ด ETag ๊ฐ์ ๋ด์์
200 OK
๋ฐํ
- ๊ฐ์ด ์ผ์นํ๋ฉด ๋ณธ๋ฌธ(body)์ ์๋ตํ๊ณ
ETag ์ข ๋ฅ
ETag๋ ๊ฒ์ฆ ๊ฐ๋์ ๋ฐ๋ผ Strong ETag์ Weak ETag ๋ ๊ฐ์ง ์ข ๋ฅ๋ก ๋๋๋ค.
- Strong ETag
- ๋ฆฌ์์ค ๋ด์ฉ์ด ๋ฐ์ดํธ ๋จ์๊น์ง ์์ ํ ์ผ์นํด์ผ ๊ฐ์ ๊ฐ์ผ๋ก ๊ฐ์ฃผ
- ๋ฆฌ์์ค๊ฐ ์กฐ๊ธ์ด๋ผ๋ ๋ณ๊ฒฝ๋๋ฉด ETag ๊ฐ์ด ๋ณ๊ฒฝ๋จ
- ํ๊ธฐ ์์:
"abcdefg"
(์ ๋์ฌ ์์)
- Weak ETag
- ๋ฆฌ์์ค๊ฐ ์๋ฏธ์ ๋์ผํ๋ค๋ฉด ๋ฐ์ดํธ ๋จ์ ์ฐจ์ด๋ฅผ ๋ฌด์ํ๊ณ ๊ฐ์ ๊ฐ์ผ๋ก ๊ฐ์ฃผ
- ๊ด๊ณ ๋ฐฐ๋, ๋์ ํ์์คํฌํ ๋ฑ ์๋ฏธ ์๋ ๋ณ๊ฒฝ์ ํ์ฉํ ๋ ์ฃผ๋ก ์ฌ์ฉ
- ํ๊ธฐ ์์:
W/"abcdefg"
(W/
์ ๋์ฌ ์ถ๊ฐ)
Weak ETag๋ ์๋ฏธ์ ์ํฅ์ ์ฃผ์ง ์๋ ๋ถ๋ถ(๋์ ํ์์คํฌํ, ๊ด๊ณ ๋ฐฐ๋ ๋ฑ)์ ์ ๊ฑฐํ๊ฑฐ๋ ์ ๊ทํํ ๋ค, ๋จ์ ์ฝํ ์ธ ๋ฅผ ํด์(hash)ํ์ฌ ์์ฑํ๋ค. ์ ๊ทํ๋ ์๋ณธ ๋ฐ์ดํฐ์์ ๋ถํ์ํ๊ฑฐ๋ ์๋ฏธ ์๋ ๋ถ๋ถ์ ์ ๊ฑฐํ๊ณ , ์ผ์ ํ ํํ๋ก ํต์ผํ๋ ๊ณผ์ ์ ์๋ฏธํ๋ค. ์๋ฅผ ๋ค์ด, HTML ํ์์คํฌํ๋ ๋ค์๊ณผ ๊ฐ์ด ์ ๊ทํํ ์ ์๋ค.
<!-- ์ ๊ทํ ์ -->
<div class="updated">2025-05-04 12:34</div>
<!-- ์ ๊ทํ ํ -->
<div class="updated"></div>
ETag ๊ฐ
ETag ๊ฐ์ ์ผ๋ฐ์ ์ผ๋ก ํฐ๋ฐ์ดํ๋ก ๊ฐ์ผ ๋ฌธ์์ด ํํ๋ก ํํํ๋ฉฐ, ๋ณ๋์ ํ์ค ํฌ๋งท์ ์์ง๋ง ์ฃผ๋ก ๋ค์๊ณผ ๊ฐ์ ๋ฐฉ์์ผ๋ก ์์ฑํ๋ค.
- ์ฝํ ์ธ ๋ด์ฉ์ ํด์ ๊ฐ (MD5, SHA1 ๋ฑ)
- ๋ง์ง๋ง ์์ ์๊ฐ์ ํด์ ๊ฐ
- ๋จ์ํ ๋ฆฌ๋น์ ๋ฒํธ ๋๋ ๋ฒ์ ๋ฒํธ
์ ๋ฐ์ดํธ ์์ค
์ฌ๋ฌ ํด๋ผ์ด์ธํธ๊ฐ ๋์ผํ ๋ฆฌ์์ค๋ฅผ ๊ฑฐ์ ๋์์ ์ฝ๊ณ ๊ฐ๊ฐ ์์ ์ ์๋ํ๋ฉด, ๋์ค์ ์ฒ๋ฆฌ๋ ๋ณ๊ฒฝ์ด ์์ ๋ณ๊ฒฝ์ ๋ฎ์ด์ฐ๋ ์
๋ฐ์ดํธ ์์ค(Lost Update) ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๋ค. ์ด๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด If-Match
ํค๋๋ฅผ ์ฌ์ฉํ์ฌ ํด๋ผ์ด์ธํธ๊ฐ ๋ณด์ ํ ETag์ ์๋ฒ์ ETag๊ฐ ์ผ์นํ ๋๋ง ๋ณ๊ฒฝ ์์
์ ์ํํ๋๋ก ์กฐ๊ฑด๋ถ ์์ฒญ์ ๋ณด๋ผ ์ ์๋ค.
- ํด๋ผ์ด์ธํธ A, B๊ฐ ๋์์ ๋ฆฌ์์ค ์กฐํ
- A์ B๊ฐ ๊ฐ๊ฐ
GET
์์ฒญ - ์๋ฒ๋
ETag: "v1"
์๋ต
- A์ B๊ฐ ๊ฐ๊ฐ
- A๊ฐ ๋จผ์ ๋ณ๊ฒฝ ์์ฒญ
- A๋
If-Match: "v1"
ํค๋์ ํจ๊ปPUT
์์ฒญ - ์๋ฒ๋ ETag ์ผ์น ํ์ธ ํ ์
๋ฐ์ดํธ ์ํ → ETag๋ฅผ
"v2"
๋ก ๊ฐฑ์ ํ๊ณ200 OK
๋ฐํ
- A๋
- B๊ฐ ๋ค์ด์ด ๋ณ๊ฒฝ ์์ฒญ
- B๋ ์ฌ์ ํ
ETag: "v1"
๋ฅผ ์ฌ์ฉํ์ฌPUT
์์ฒญ - ์๋ฒ์ ETag๋ ์ด๋ฏธ
"v2"
์ด๋ฏ๋ก B์ ETag์ ๋ถ์ผ์น →412 Precondition Failed
๋ฐํ
- B๋ ์ฌ์ ํ
๋ง์ฝ 3๋ฒ์์ ์กฐ๊ฑด ์์ด B์ ๋ด์ฉ์ผ๋ก ๋ฎ์ด์ด๋ค๋ฉด A์ ๋ณ๊ฒฝ ๋ด์ฉ์ด ์ฌ๋ผ์ง๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค. If-Match
์กฐ๊ฑด์ด ์คํจํ์ ๋ ์ผ๋ฐ์ ์ผ๋ก 412 Precondition Failed
๋ก ์๋ตํ๋ค. ์์ฒญ์ด ๊ฑฐ๋ถ๋ ํด๋ผ์ด์ธํธ๊ฐ ์ถฉ๋์ ํด๊ฒฐํ๋ ค๋ฉด ์ต์ ๋ฆฌ์์ค๋ฅผ ๋ค์ GET ํด์ผ ํ๋ค.
ETag์ Cache-Control
Cache-Control์ ๋ธ๋ผ์ฐ์ ์ ์ค๊ฐ ์๋ฒ(Proxy, CDN ๋ฑ)๊ฐ ์ด๋ค ๋ฐฉ์์ผ๋ก ์๋ต์ ์บ์ฑํ ์ง ์ง์ ํ๋ ํค๋๋ก, ์บ์ฑ ๊ฐ๋ฅ ์ฌ๋ถ(public
, private
, no-store
), ์บ์ ์ ํจ ๊ธฐ๊ฐ(max-age
), ์ฌ๊ฒ์ฆ ๋ฐฉ์(no-cache
, must-revalidate
) ๋ฑ์ ์ค์ ํ ์ ์๋ค.
Cache-Control๊ณผ ETag๋ ์น ์บ์ฑ ์ ๋ต์์ ์ํธ ๋ณด์์ ์ธ ์ญํ ์ ์ํํ์ฌ, ํจ๊ป ์ฌ์ฉํ๋ฉด ๋ ํจ์จ์ ์ธ ์บ์ฑ ์ ์ฑ ์ ๊ตฌํํ ์ ์๋ค.
์์ฃผ ๋ณ๊ฒฝ๋๋ ๋์ ์ธ ๋ฆฌ์์ค๋ no-cache
์ค์ ์ ์ ์ฉํ์ฌ ๋งค๋ฒ ์๋ฒ์ ์ฌ๊ฒ์ฆ์ ์์ฒญํ๊ฒ ํ๊ณ , ETag๋ฅผ ํตํด ์ฝํ
์ธ ๊ฐ ๋ณ๊ฒฝ๋์ง ์์์ ๋ 304 Not Modified
๋ก ์๋ตํ์ฌ ๋ถํ์ํ ๋ฐ์ดํฐ ์ ์ก์ ์ค์ผ ์ ์๋ค.
Cache-Control: no-cache
ETag: "v123"
no-cache
: ์บ์ ๋ฐ์ดํฐ ์ฌ์ฉ ์ ๋งค๋ฒ ์๋ณธ ์๋ฒ์ ์ฌ๊ฒ์ฆmust-revalidate
: ๋ง๋ฃ๋ ์บ์ ๋ฐ์ดํฐ๋ ์๋ณธ ์๋ฒ ์ฌ๊ฒ์ฆ ์์ด ์ฌ์ฉ ๋ถ๊ฐ
๋ณ๊ฒฝ์ด ๊ฑฐ์ ์๋ ์ ์ ์ธ ๋ฆฌ์์ค๋ max-age
์ immutable
์ ํจ๊ป ์ค์ ํ์ฌ ์ ํจ ๊ธฐ๊ฐ ๋์ ์๋ฒ ์ฌ๊ฒ์ฆ ์์ฒญ ์์ด ์บ์ ๋ ์๋ต์ ์ฌ์ฉํ๋๋ก ํ๋ค. max-age
๊ธฐ๊ฐ ๋์ ETag๋ฅผ ์ด์ฉํ ์ฌ๊ฒ์ฆ์ด ์ผ์ด๋์ง ์์ง๋ง, ์บ์๊ฐ ๋ง๋ฃ๋๊ฑฐ๋ immutable
์ ์ง์ํ์ง ์๋ ์ผ๋ถ ํ๊ฒฝ์์์ ์ฌ๊ฒ์ฆ์ ์ํด ETag๋ฅผ ํจ๊ป ๋ณด๋ด๋ ๊ฒ์ด ์ผ๋ฐ์ ์ด๋ค.
Cache-Control: max-age=31536000, immutable
ETag: "abc456"
public
: ๋ธ๋ผ์ฐ์ ์ ์ค๊ฐ ์๋ฒ(ํ๋ก์, CDN ๋ฑ) ๋ชจ๋ ์๋ต์ ์บ์ฑํ๊ณ ์ฌ์ฌ์ฉํ ์ ์๋๋ก ํ์ฉmax-age=31536000
: ์บ์ ์์ฑ ํ 1๋ (31,536,000์ด) ๋์ fresh ์ํ ์ ์งimmutable
: ์ ํจ ๊ธฐ๊ฐ ๋ด ๋ฆฌ์์ค๊ฐ ๋ณ๊ฒฝ๋์ง ์์์ ๋ํ๋ด๋ฉฐ, ํด๋น ๊ธฐ๊ฐ ๋์ ๋ธ๋ผ์ฐ์ ๊ฐ ์ฌ๊ฒ์ฆ ์์ฒญ์ ๋ณด๋ด์ง ์๋๋ก ์ง์
๋ ํผ๋ฐ์ค
ETag - HTTP | MDN
ETag HTTP ์๋ต ํค๋๋ ํน์ ๋ฒ์ ์ ๋ฆฌ์์ค๋ฅผ ์๋ณํ๋ ์๋ณ์์ ๋๋ค. ์น ์๋ฒ๊ฐ ๋ด์ฉ์ ํ์ธํ๊ณ ๋ณํ์ง ์์์ผ๋ฉด, ์น ์๋ฒ๋ก full ์์ฒญ์ ๋ณด๋ด์ง ์๊ธฐ ๋๋ฌธ์, ์บ์ฌ๊ฐ ๋ ํจ์จ์ ์ด๊ฒ ๋๊ณ , ๋์ญํญ
developer.mozilla.org
'๐ช Programming' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[JS] ์๋ฐ์คํฌ๋ฆฝํธ 6์ค๋ก ์ด๋ฏธ์ง ๋น๊ต ์ฌ๋ผ์ด๋ ๋ง๋ค๊ธฐ (0) | 2025.04.17 |
---|---|
[HTTP] Cache-Control ํค๋ (0) | 2025.03.31 |
[Next.js] API ๋ผ์ฐํธ ๋ณดํธํ๊ธฐ - Unkey (0) | 2025.03.30 |
[Next.js] dnd-kit์ ํ์ฉํ ์นธ๋ฐ(Kanban) ๋ณด๋ ๋๋๊ทธ ์ค ๋๋กญ ๊ตฌํ (0) | 2025.03.18 |
[UI] Shadcn DropdownMenu์์ Dialog ์๋ ๋ซํ ๋ฌธ์ ํด๊ฒฐ (0) | 2025.03.09 |
๋๊ธ
์ด ๊ธ ๊ณต์ ํ๊ธฐ
-
๊ตฌ๋
ํ๊ธฐ
๊ตฌ๋ ํ๊ธฐ
-
์นด์นด์คํก
์นด์นด์คํก
-
๋ผ์ธ
๋ผ์ธ
-
ํธ์ํฐ
ํธ์ํฐ
-
Facebook
Facebook
-
์นด์นด์ค์คํ ๋ฆฌ
์นด์นด์ค์คํ ๋ฆฌ
-
๋ฐด๋
๋ฐด๋
-
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
-
Pocket
Pocket
-
Evernote
Evernote
๋ค๋ฅธ ๊ธ
-
[JS] ์๋ฐ์คํฌ๋ฆฝํธ 6์ค๋ก ์ด๋ฏธ์ง ๋น๊ต ์ฌ๋ผ์ด๋ ๋ง๋ค๊ธฐ
[JS] ์๋ฐ์คํฌ๋ฆฝํธ 6์ค๋ก ์ด๋ฏธ์ง ๋น๊ต ์ฌ๋ผ์ด๋ ๋ง๋ค๊ธฐ
2025.04.17 -
[HTTP] Cache-Control ํค๋
[HTTP] Cache-Control ํค๋
2025.03.31 -
[Next.js] API ๋ผ์ฐํธ ๋ณดํธํ๊ธฐ - Unkey
[Next.js] API ๋ผ์ฐํธ ๋ณดํธํ๊ธฐ - Unkey
2025.03.30 -
[Next.js] dnd-kit์ ํ์ฉํ ์นธ๋ฐ(Kanban) ๋ณด๋ ๋๋๊ทธ ์ค ๋๋กญ ๊ตฌํ
[Next.js] dnd-kit์ ํ์ฉํ ์นธ๋ฐ(Kanban) ๋ณด๋ ๋๋๊ทธ ์ค ๋๋กญ ๊ตฌํ
2025.03.18