이전에 받은 ETag를 `If-None-Match`로 되돌려 보내, 리소스가 바뀌지 않았으면 304 Not Modified만 받아 대역폭을 아끼는 조건부 GET 레시피입니다.
이전에 받은 ETag를 `If-None-Match`로 되돌려 보내, 리소스가 바뀌지 않았으면 304 Not Modified만 받아 대역폭을 아끼는 조건부 GET 레시피입니다.
# 1) first request returns an ETag
curl -i https://api.example.com/config
# ETag: "a1b2c3"
# 2) revalidate: send it back, get 304 if unchanged
curl -i https://api.example.com/config \
-H 'If-None-Match: "a1b2c3"'const first = await fetch('/config');
const etag = first.headers.get('ETag');
const next = await fetch('/config', {
headers: { 'If-None-Match': etag }
});
if (next.status === 304) {
// not modified — reuse cached body
}import requests
r1 = requests.get('https://api.example.com/config')
etag = r1.headers['ETag']
r2 = requests.get('https://api.example.com/config',
headers={'If-None-Match': etag})
print(r2.status_code) # 304 if unchanged (r2.content is empty)첫 응답의 `ETag`(리소스 버전 식별자)를 저장해 두었다가, 다음 요청에 `If-None-Match: "<etag>"`로 보냅니다. 리소스가 그대로면 서버는 본문 없이 304를 반환하고, 클라이언트는 캐시에 둔 이전 본문을 재사용합니다. 바뀌었으면 200과 새 본문·새 ETag가 옵니다.
ETag는 `"..."`로 감싼 강한(strong) 검증자와 `W/"..."`로 시작하는 약한(weak) 검증자가 있습니다. 약한 ETag는 의미상 동등하면 같은 것으로 취급해 바이트 단위 일치가 필요한 Range 요청 등에는 부적합합니다.
시간 기반 대안으로 `Last-Modified` + `If-Modified-Since`가 있지만 초 단위 해상도라 정밀도가 낮습니다. 조건부 요청은 쓰기(PUT/DELETE)에서는 `If-Match`로 낙관적 잠금에 쓰이며, 조건 불일치 시 412 Precondition Failed가 납니다.