Expires
고친 사람 github-actions[bot]
Expires 는 받아 둔 응답을 언제까지 서버에 다시 묻지 않고 써도 되는지 알려 주는 응답 헤더입니다. 서버는 여기에 시각 하나를 적습니다. 캐시는 그 시각 전까지 저장해 둔 응답을 서버에 묻지 않고 내줄 수 있습니다. 쿠키에 붙는 같은 이름의 속성은 이것과 다른 것입니다.
쉽고 빠른 이해
Expires 는 응답에 붙는 유통기한입니다. 서버가 Expires: Thu, 01 Dec 1994 16:00:00 GMT 를
실어 보내면 캐시는 그 시각까지 이 응답을 서버에 다시 묻지 않고 쓸 수 있습니다.
이게 없으면 캐시는 저장해 둔 응답을 언제까지 믿어도 되는지 스스로 짐작해야 합니다. 내용이 바뀌었는지는 서버만 알기 때문입니다.
캐시는 이렇게 씁니다.
- 적힌 시각에서 응답이 만들어진 시각을 빼 쓸 수 있는 기간을 구합니다
- 그 기간 안에는 저장해 둔 응답을 서버에 묻지 않고 내줄 수 있습니다
- 기간이 지나면 대개 서버에 물어 아직 맞는 응답인지 확인받고 씁니다
대가는 적는 쪽의 시계에 기댄다는 점입니다. 시계가 없는 서버는 이 값을 적으면 안 됩니다. 기간을 초로 적는 max-age 가 같은 응답에 있으면 이 값은 무시됩니다.
상세
Expires 는 HTTP(HyperText Transfer Protocol, 하이퍼텍스트 전송 프로토콜) 응답에 붙는 헤더 필드입니다. 헤더는 응답 본문 앞에 딸려 오는 정보 묶음입니다. 그 안의 한 줄 한 줄이 필드입니다.
이 필드에는 시각 하나가 들어갑니다. 그 시각이 지나면 이 응답은 낡은 것으로 여겨집니다.
이 절은 응답에 실린 Expires 한 줄을 놓고 봅니다. 캐시가 이 값을 읽어 응답을 저장해도 되는지, 저장한 응답을 얼마 동안 다시 써도 되는지 정하는 과정을 따라갑니다.
캐시는 받은 응답을 저장해 두었다가 같은 요청이 오면 서버까지 가지 않고 내주는 저장소입니다. 브라우저 안의 캐시가 그렇습니다. 여러 사용자가 함께 거치는 프록시 서버의 캐시도 그렇습니다.
캐시는 손에 든 응답이 아직 맞는지 혼자서는 모릅니다. 원본이 바뀌었는지는 응답의 원본을 가진 서버만 압니다. 이 서버가 오리진 서버입니다. 오리진 서버는 앞날의 만료 시각을 미리 적어 보냅니다.
오리진 서버는 대개 그 시각 전에는 내용이 의미 있게 바뀔 가능성이 낮다고 보고 이 값을 정합니다.
신선한 응답과 낡은 응답
응답이 만들어진 뒤 흐른 시간이 그 응답의 나이입니다. 오리진 서버가 응답을 만든 때부터 만료 시각까지의 길이는 신선도 수명입니다.
나이가 신선도 수명을 안 넘었으면 신선한 응답입니다. 넘었으면 낡은 응답입니다. 신선한 응답은 서버에 묻지 않고 내줄 수 있습니다.
낡은 응답은 대개 서버에 아직 맞는지 확인받은 뒤에 다시 씁니다. 이 확인을 검증이라고 부릅니다.
아래 괄호 속 대문자 낱말은 표준이 정한 요구의 강도입니다. MUST 와 MUST NOT 은 반드시 지킬 요구입니다. SHOULD 는 까닭이 있으면 어길 수 있는 권고입니다. MAY 는 해도 되고 안 해도 되는 것입니다.
Expires 처럼 오리진 서버가 직접 정해 준 시각이 명시적 만료 시각입니다. 서버가 아무것도 안 정해 주면 캐시는 다른 필드 값으로 만료 시각을 추정해 붙여도 됩니다(MAY). 자원을 마지막으로 고친 시각을 싣는 Last-Modified 필드가 그런 재료입니다.
명시적 만료 시각이 저장된 응답에 있으면 추정을 써서는 안 됩니다(MUST NOT).
값의 꼴
값은 시각 하나입니다. 적는 꼴은 HTTP-date 라는 이름으로 정해져 있습니다.
Expires: Thu, 01 Dec 1994 16:00:00 GMT
요일 · 일 · 달 · 해 · 시각을 이 순서로 적습니다. 끝의 GMT(Greenwich Mean Time, 그리니치 평균시)는 시간대 표시입니다. HTTP-date 는 시각을 언제나 UTC(Coordinated Universal Time, 협정 세계시)로 나타냅니다. GMT 는 UTC 라는 이름보다 앞서 쓰던 이름입니다.
권장하는 꼴의 이름은 IMF-fixdate 입니다. Internet Message Format(인터넷 메시지 형식)이 쓰는 날짜 표기에서 길이가 고정되고 시간대가 하나뿐인 부분만 떼어 낸 꼴입니다. 1995년 전에는 서버들이 세 가지 꼴을 섞어 썼습니다. 옛 구현과 맞추려고 옛 꼴 둘도 함께 정의되어 있습니다.
| 꼴 | 보기 | 처지 |
|---|---|---|
| IMF-fixdate | Sun, 06 Nov 1994 08:49:37 GMT |
권장 꼴. 보내는 쪽은 이 꼴만 만들어야 합니다(MUST) |
| RFC(Request for Comments) 850 꼴 | Sunday, 06-Nov-94 08:49:37 GMT |
낡은 꼴 |
| C 언어 asctime() 꼴 | Sun Nov 6 08:49:37 1994 |
낡은 꼴. 시간대 표시가 없어 UTC 로 봅니다 |
받는 쪽은 응답을 받아 그 값을 읽는 프로그램입니다. 캐시도 받는 쪽입니다. 받는 쪽은 세 꼴을 모두 받아들여야 합니다(MUST).
HTTP-date 는 원래 대소문자를 가립니다. 캐시는 신선도를 계산할 때 날짜를 잘못 읽는 흔한 문제를 피하려고 아래 네 규칙을 지킵니다. 규칙을 늦추는 것은 대소문자 하나뿐입니다. 나머지 셋은 계산을 더 단단히 묶습니다.
| 캐시가 지킬 규칙 | 강도 |
|---|---|
| 날짜를 대소문자 가리지 않고 맞춰 봅니다 | SHOULD |
| 캐시 안의 시각 눈금이 HTTP-date 보다 거칠면 받은 값과 같거나 그보다 이른 가장 가까운 시각으로 담습니다 | MUST |
| 캐시가 놓인 지역의 시간대가 나이나 만료 시각의 계산·비교에 끼어들게 하지 않습니다 | MUST NOT |
| GMT 가 아닌 시간대 약어가 붙은 날짜는 만료 계산에서 무효로 봅니다 | SHOULD |
둘째 줄의 눈금은 캐시가 시각을 담는 가장 작은 단위입니다. HTTP-date 는 초까지 적습니다. 캐시가 그보다 큰 단위로 시각을 담으면 받은 Expires 값을 아래로 맞춰 담습니다. 그러면 만료 시각이 받은 값보다 늦어지지 않습니다.
넷째 줄에서 무효로 본 날짜를 그 뒤 어떻게 셈하는지는 이 규칙들이 더 적지 않습니다. 날짜로 아예 읽히지 않는 값은 다음 소절의 규칙을 받습니다.
지난 시각과 깨진 값
캐시는 날짜로 읽히지 않는 값을 이미 지난 시각으로 해석해야 합니다(MUST). 숫자 0 한 글자가
대표적입니다. 깨진 값은 응답을 오래 붙드는 쪽이 아니라 곧바로 낡게 만드는 쪽으로 작동합니다.
오리진 서버가 지난 시각을 일부러 적기도 합니다. 그 응답은 받자마자 낡은 것이 됩니다. 캐시는 대개 다시 쓸 때마다 검증부터 받습니다. 요청마다 캐시가 검증을 거치게 하고 싶을 때 쓰는 방법입니다.
신선도 수명을 구하는 차례
신선도 수명을 정하는 단서는 Expires 하나가 아닙니다. Cache-Control 은 캐시에게 줄 지시를 적어 보내는 헤더 필드입니다. 그 안의 지시 하나하나가 지시어입니다. max-age 와 s-maxage 는 신선도 수명을 초 수로 적는 지시어입니다.
둘은 누가 읽느냐가 다릅니다. max-age 는 모든 캐시가 읽습니다. s-maxage 는 공유 캐시만 읽습니다.
공유 캐시는 여러 사용자가 함께 쓰는 캐시입니다. CDN(Content Delivery Network, 콘텐츠 전송 네트워크)이나 프록시 서버의 캐시가 여기 듭니다. 한 사용자만 쓰는 브라우저 캐시 같은 것은 개인 캐시입니다.
또 하나의 재료는 Date 필드입니다. Date 는 그 응답 메시지가 만들어진 시각을 싣습니다. 값의 꼴은 Expires 와 같은 HTTP-date 입니다.
캐시는 단서를 아래 차례로 따져 처음 맞는 것을 씁니다.
flowchart TD
A["공유 캐시이고 s-maxage 가 있나"] -->|있다| S["s-maxage 값을 쓴다"]
A -->|없다| B["max-age 가 있나"]
B -->|있다| M["max-age 값을 쓴다"]
B -->|없다| C["Expires 가 있나"]
C -->|있다| E["Expires 에서 Date 를 뺀다"]
C -->|없다| H["캐시가 만료 시각을 추정해도 된다"]
Expires 는 세 번째 칸입니다. max-age 가 없을 때 차례가 옵니다. 공유 캐시라면 s-maxage 도 없어야 합니다. 개인 캐시는 첫 칸을 건너뛰므로 s-maxage 가 있어도 max-age 만 없으면 Expires 를 씁니다.
그때 신선도 수명은 Expires 값에서 Date 값을 뺀 길이입니다. Date 가 없으면 응답을 받은 시각을 대신 씁니다.
예를 들어 Date 가 오전 9시이고 Expires 가 오전 10시면 신선도 수명은 한 시간입니다. 캐시는 그 한 시간 동안 이 응답을 서버에 묻지 않고 내줄 수 있습니다.
Date 를 빼는 까닭은 시계 엇갈림을 줄이려는 것입니다. 시계 엇갈림은 두 기계의 시계가 서로 다른 시각을 가리키는 일입니다. Expires 와 Date 는 둘 다 오리진 서버의 시계에서 나옵니다. 캐시의 시계가 틀려도 뺀 길이는 변하지 않습니다.
한 응답에 Expires 줄이 둘 이상이면 첫 줄을 쓰거나 응답을 낡은 것으로 보기를 권합니다. 신선도 정보가 깨진 응답도 낡은 것으로 보기를 권합니다.
max-age 와의 우선순위
응답에 max-age 지시어가 있으면 받는 쪽은 Expires 를 무시해야 합니다(MUST). 공유 캐시는 s-maxage 지시어가 있을 때도 Expires 를 무시해야 합니다(MUST).
이럴 때 Expires 값은 Cache-Control 을 아직 구현하지 않은 받는 쪽만을 위한 것입니다. 서버는 둘을 함께 실어 보낼 수 있습니다. Cache-Control 을 아는 캐시는 초 수를 읽습니다. 모르는 옛 캐시는 시각을 읽습니다.
저장해도 되는 응답
Expires 는 저장한 응답을 얼마 동안 쓰나만 정하지 않습니다. 캐시가 그 응답을 저장해도 되는지 가르는 단서이기도 합니다.
캐시는 몇 가지 조건을 모두 채운 응답만 저장할 수 있습니다. 하나라도 못 채우면 저장해서는 안 됩니다(MUST NOT). 요청 메서드를 캐시가 알아볼 것, 저장을 막는 no-store 지시어가 응답에 없을 것이 그 조건에 듭니다.
마지막 조건은 응답이 아래 단서 가운데 하나 이상을 지닐 것입니다. 목록의 상태 코드는 응답 첫 줄에 실리는 세 자리 수입니다.
- Expires 필드
- max-age 지시어
- 공유 캐시라면 s-maxage 지시어
- 추정 만료로 재사용할 수 있다고 정해 둔 상태 코드
- 그 밖에 Cache-Control 의 몇몇 지시어
200 · 404 · 410 같은 상태 코드는 추정 만료로 재사용할 수 있다고 정해져 있습니다. 이렇게 정해 둔 상태 코드가 아니어도 응답에 Expires 가 있으면 마지막 조건을 채웁니다.
명시적 신선도 정보가 있으면 최종 상태 코드를 단 응답은 어느 것이든 캐시될 수 있습니다. 최종 상태 코드는 중간 안내(1xx)가 아니라 요청에 대한 마지막 답을 주는 상태 코드입니다.
시계가 없는 서버
시계는 지금 시각을 UTC 에 무리 없이 가깝게 알려 주는 장치나 구현입니다. 시계는 NTP(Network Time Protocol, 네트워크 시간 프로토콜) 같은 프로토콜로 UTC 에 맞춰 두기를 권합니다.
Expires 는 절대 시각이라 적는 쪽의 시계가 있어야 뜻이 섭니다. 시계가 없는 오리진 서버는 Expires 를 만들어 보내면 안 됩니다(MUST NOT). 그런 서버는 Date 필드도 만들면 안 됩니다(MUST NOT).
예외는 둘입니다. 값이 언제나 지난 고정 시각인 경우입니다. 또는 시계를 가진 다른 시스템이 그 값을 미리 자원에 붙여 둔 경우입니다.
이 값이 하지 않는 일
Expires 가 있다고 원본이 그 시각에 바뀌거나 사라진다는 뜻은 아닙니다. 그 전에 바뀔 수도 있습니다. 그 뒤에도 바뀌지 않을 수 있습니다.
신선도는 캐시의 동작에만 걸립니다. 브라우저가 화면을 새로 그리게 하거나 자원을 다시 불러오게 강제하는 데에는 못 씁니다.
예전 HTTP 는 Expires 값을 1년 뒤까지로 묶어 두었습니다. 지금은 더 긴 신선도 수명을 금지하지 않습니다. 다만 아주 큰 값은 문제를 일으킨 적이 있습니다. 시각을 32비트 정수로 셀 때 넘치는 일이 그 예입니다.
먼 만료 시각을 받아도 많은 캐시는 그보다 훨씬 일찍 응답을 지웁니다.
출처 문서
정본은 RFC 9111 입니다. 제목은 HTTP Caching 입니다. 2022년 6월에 나왔습니다. IETF(Internet Engineering Task Force, 국제 인터넷 표준화 기구)의 표준 트랙(Standards Track) 문서입니다.
RFC 9111 은 STD(Standard) 98 이라는 표준 번호도 받았습니다. 직전 판 RFC 7234 를 폐기했습니다.
Expires 의 정의는 §5.3 에 있습니다. 신선도 계산은 §4.2 가 맡습니다. 저장 조건은 §3 에 있습니다.
값의 꼴과 Date 필드는 RFC 9110 이 정합니다. 제목은 HTTP Semantics 입니다. 같은 2022년 6월에 나온 STD 97 입니다.
HTTP-date 는 RFC 9110 §5.6.7 에 있습니다. Date 는 §6.6.1 에 있습니다. 추정 만료로 재사용할 수 있는 상태 코드 목록은 §15.1 에 있습니다.
HTTP/1.0 을 적은 RFC 1945 에 이미 Expires 가 있었습니다. 1996년 5월에 나왔습니다. 분류는 정보 제공용(Informational)입니다. 표준 트랙 문서가 아닙니다.
HTTP/1.1 의 RFC 2616 은 §14.21 에서 이 필드를 다룹니다. RFC 7234 가 2616 을 폐기했습니다. RFC 9111 이 다시 7234 를 폐기했습니다. 2616 이나 7234 의 절 번호를 인용하면 폐기된 판을 드는 것입니다.
대문자 MUST · SHOULD · MAY 의 뜻은 RFC 2119 와 RFC 8174 가 정합니다. MUST 를 어기면 표준을 안 지킨 것입니다. SHOULD 는 까닭이 있으면 어길 수 있습니다.
요구와 강도
| 요구 | 지키는 쪽 | 강도 | 절 |
|---|---|---|---|
날짜로 안 읽히는 값, 특히 0 을 이미 지난 시각으로 해석한다 |
캐시 | MUST | RFC 9111 §5.3 |
| max-age 가 있으면 Expires 를 무시한다 | 받는 쪽 | MUST | RFC 9111 §5.3 |
| s-maxage 가 있으면 Expires 를 무시한다 | 공유 캐시 | MUST | RFC 9111 §5.3 |
| 시계가 없으면 Expires 를 만들지 않는다. 지난 고정 시각과 시계 있는 시스템이 붙인 값은 예외 | 오리진 서버 | MUST NOT | RFC 9111 §5.3 |
| 조건을 다 채운 응답만 저장한다. 마지막 조건의 단서 목록에 Expires 필드가 있다 | 캐시 | MUST NOT | RFC 9111 §3 |
| 날짜를 대소문자 구분 없이 맞춰 본다 | 캐시 | SHOULD | RFC 9111 §4.2 |
| 시각 눈금이 HTTP-date 보다 거칠면 받은 값과 같거나 이른 가장 가까운 시각으로 담는다 | 캐시 | MUST | RFC 9111 §4.2 |
| 지역 시간대가 나이·만료 계산에 끼어들게 하지 않는다 | 캐시 | MUST NOT | RFC 9111 §4.2 |
| GMT 가 아닌 시간대 약어가 붙은 날짜를 무효로 본다 | 캐시 | SHOULD | RFC 9111 §4.2 |
| 명시적 만료 시각이 있으면 추정을 쓰지 않는다 | 캐시 | MUST NOT | RFC 9111 §4.2.2 |
| HTTP-date 세 꼴을 모두 받아들인다 | 받는 쪽 | MUST | RFC 9110 §5.6.7 |
| 보낼 때는 IMF-fixdate 꼴로 만든다 | 보내는 쪽 | MUST | RFC 9110 §5.6.7 |
| 시계가 없으면 Date 를 만들지 않는다 | 오리진 서버 | MUST NOT | RFC 9110 §6.6.1 |
RFC 2616 에서 바뀐 요구
| 요구 | RFC 2616 | RFC 9111 |
|---|---|---|
| 값의 꼴 | HTTP-date 가운데 RFC 1123 날짜 꼴이어야 합니다(MUST) | HTTP-date 이고 보낼 때는 IMF-fixdate (RFC 9110) |
| 먼 미래의 값 | 1년 넘게 뒤의 날짜를 보내지 않는 것이 좋습니다(SHOULD NOT). 「만료 없음」은 대략 1년 뒤 날짜로 표시합니다 | 더는 금지가 아닙니다. 대신 32비트 시각 넘침 같은 문제를 경고합니다 |
| 「이미 만료」 표시 | Date 와 같은 값을 Expires 에 적습니다 | 지난 시각을 명시적 만료 시각으로 적습니다(§4.2) |
깨진 값과 0 |
HTTP/1.1 클라이언트와 캐시가 지난 시각으로 다뤄야 합니다(MUST) | 받는 쪽 가운데 캐시가 지난 시각으로 해석해야 합니다(MUST) |
| max-age 와 함께 올 때 | max-age 가 Expires 를 덮습니다(Note) | 받는 쪽이 Expires 를 무시해야 합니다(MUST) |
| 저장해도 되는지 | 미래 날짜의 Expires 가 붙으면, 기본으로는 캐시할 수 없는 응답도 캐시할 수 있다는 뜻입니다. Cache-Control 이 달리 말하면 그쪽을 따릅니다 | 저장 조건의 단서 목록에 Expires 필드가 들어 있습니다(§3). 미래 날짜라는 한정은 그 목록 문장에 없습니다 |
시계 없는 서버의 예외도 문구가 바뀌었습니다. RFC 7234 는 「믿을 만한 시계를 가진 시스템이나 사용자」가 붙인 값을 허용했습니다. RFC 9111 은 「시계를 가진 시스템」으로 줄였습니다.
HTTP/1.0 의 RFC 1945 는 요구를 소문자로 적었습니다. 주어진 날짜를 넘겨 그 응답 내용을 캐시하면 안 된다(must not)고 적었습니다. Date 이하의 값이 오면 받는 쪽은 캐시하지 말라고 했습니다.
RFC 1945 에서 0 이나 깨진 날짜는 정당한 값이 아닙니다. 그래도 「즉시 만료」와 같게 보기를
권했습니다.
정해 두지 않은 것
- 추정 만료를 계산하는 법은 정하지 않았습니다. RFC 9111 §4.2.2 는 추정 결과가 넘으면 안 되는 한계만 둡니다
- 캐시가 응답을 얼마나 오래 들고 있는지는 정하지 않았습니다. §5.3 은 많은 캐시가 먼 만료 시각보다 훨씬 일찍 지운다고만 적습니다
- Expires 줄이 둘일 때의 처리도 강도 낱말로 정하지 않았습니다. §4.2.1 은 이것을 소문자 should 로 적습니다
- GMT 아닌 시간대 약어 때문에 무효로 본 날짜를 어떻게 셈하는지는 §4.2 가 더 정하지 않았습니다. §5.3 은 무효한 날짜 꼴을 지난 시각으로 해석하라고 적습니다
이름이 같은 쿠키 속성의 정본
쿠키의 Expires 속성은 RFC 6265 가 정합니다. 제목은 HTTP State Management Mechanism 입니다. 2011년 4월에 나온 Proposed Standard 입니다. RFC 2965 를 폐기했습니다.
이 문서를 고치는 RFC 6265bis 는 아직 Internet-Draft 입니다. RFC 번호가 없습니다. 쿠키 쪽 규칙은 RFC 6265 §4.1.2.1 · §5.1.1 · §5.2.1 · §5.3 에 있습니다.
예시
응답에 실린 Expires 한 줄
Expires: Thu, 01 Dec 1994 16:00:00 GMT
1994년 12월 1일 목요일 16시 0분 0초, 그리니치 평균시입니다. 이 시각이 지나면 응답은 낡은 것이 됩니다. 같은 응답에 Cache-Control 의 max-age 가 없어야 이 값이 쓰입니다. 공유 캐시라면 s-maxage 도 없어야 합니다.
그때 신선도 수명은 이 값에서 같은 응답의 Date 값을 뺀 길이입니다.
날짜가 아닌 값
Expires: 0
0 은 날짜로 읽히지 않습니다. 캐시는 이 값을 이미 지난 시각으로 해석해야 합니다. 이 응답은
받는 순간 낡은 것이 됩니다. HTTP/1.0 시절에도 이 값은 「즉시 만료」로 보도록 권했습니다.
nginx 의 expires 지시어
nginx 는 설정 한 줄로 응답의 Expires 와 Cache-Control 을 붙이거나 고칩니다. 이 지시어는 응답 코드가 200 · 201 · 204 · 206 · 301 · 302 · 303 · 304 · 307 · 308 일 때만 작동합니다. 아래 표의 no-cache 는 저장한 응답을 다시 쓰기 전에 매번 서버의 검증을 받으라는 Cache-Control 지시어입니다.
expires epoch;
expires max;
| 설정 | Expires 에 들어가는 값 | Cache-Control |
|---|---|---|
expires epoch; |
Thu, 01 Jan 1970 00:00:01 GMT |
no-cache |
expires max; |
Thu, 31 Dec 2037 23:55:55 GMT |
10년으로 정합니다 |
| 양수 또는 0 시간 t | 지금 시각에 t 를 더한 값 | max-age=t (t 를 초로 센 값) |
| 음수 시간 t | 지금 시각에 t 를 더한 값 | no-cache |
expires off; |
붙이거나 고치지 않음 | 붙이거나 고치지 않음 |
문법은 expires [modified] time; 입니다. expires off; 가 기본값입니다. 시간 앞에
modified 를 붙이면 지금 시각 대신 파일을 고친 시각에 시간을 더합니다.
epoch 는 언제나 지난 고정 시각을 적습니다. 받자마자 낡은 응답이 됩니다. max 가 적는
2037년 12월 31일은 32비트 정수로 초를 세는 시각이 넘치는 2038년 1월보다 앞입니다.
배경
캐시는 오리진 서버에 아예 요청을 보내지 않을 때 가장 잘 돕니다. 그러려면 저장해 둔 응답이 언제까지 맞는지 알아야 합니다. 자원이 언제 바뀔지는 그 정보를 내놓는 쪽이 압니다.
HTTP/1.0 의 Expires 는 정보를 내놓는 쪽이 자원이 얼마나 자주 바뀌는지 넌지시 알리는 수단이었습니다. 특정 날짜에 바뀔 것을 알거나 그럴 것 같다고 의심만 해도 그 날짜를 적기를 권했습니다.
HTTP/1.1 에서는 둘이 같이 오면 Expires 가 더 짧은 기간을 가리켜도 max-age 지시어가 이깁니다. 이 규칙으로 오리진 서버는 한 응답 안에서 HTTP/1.1 캐시에 HTTP/1.0 캐시보다 긴 만료 시간을 줄 수 있습니다. 일부 HTTP/1.0 캐시가 나이나 만료 시각을 잘못 계산한다면 이것이 쓸모 있을 수 있습니다. 그 잘못은 어쩌면 시계가 서로 안 맞은 탓일 수 있습니다.
경계
Set-Cookie 헤더에 붙는 Expires 속성도 이 필드인가. 아닙니다.
Set-Cookie: lang=en-US; Expires=Wed, 09 Jun 2021 10:18:14 GMT
둘 다 「이 시각이 지나면 만료」라는 절대 시각이라 이름이 겹칩니다. 갈리는 것은 무엇이 만료되나와 값을 읽는 규칙입니다.
| Expires 헤더 필드 | 쿠키의 Expires 속성 | |
|---|---|---|
| 실리는 곳 | 응답 헤더의 한 줄 | Set-Cookie 헤더 값 안의 속성 |
| 만료되는 것 | 캐시에 저장된 응답 | 브라우저에 저장된 쿠키 |
| 값을 읽는 규칙 | HTTP-date 꼴 | 쿠키 전용 날짜 해석 절차 |
| 날짜로 안 읽힐 때 | 이미 지난 시각으로 봅니다 | 그 속성을 무시합니다 |
| 함께 오면 이기는 상대 | Cache-Control 의 max-age · s-maxage | 쿠키의 Max-Age 속성 |
가장 크게 갈리는 줄은 날짜로 안 읽힐 때입니다. 캐시 쪽은 깨진 값을 받으면 응답을 곧바로 낡게 만듭니다. 쿠키 쪽은 깨진 값을 받으면 그 속성이 없었던 것처럼 넘어갑니다. 같은 문자열이라도 어느 헤더에 실렸느냐에 따라 결과가 반대로 갈립니다.
관련 항목
이 필드를 정의하고 이어받은 표준 문서
RFC 9111 · RFC 9110 · RFC 7234 · RFC 2616 · RFC 1945 · RFC 2119 · HTTP · IETF
같은 응답에서 신선도를 함께 정하는 필드
Cache-Control · max-age · s-maxage · no-cache · Age · Date
이 시각을 적고 맞추는 시간 규약
HTTP-date · IMF-fixdate · UTC · GMT · NTP · 시계 엇갈림 · 2038 문제
이 값이 좌우하는 캐시 개념
신선도 · 신선도 수명 · 나이 · 낡은 데이터 · 검증 · 무효화 · 축출 · TTL
이 값을 읽고 재사용을 판단하는 캐시
HTTP 캐시 · 브라우저 캐시 · CDN · 공유 캐시 · 프록시 · 리버스 프록시 캐시 · 오리진 서버
값이 만료된 뒤에 쓰는 조건부 요청 수단
조건부 요청 · ETag · Last-Modified · If-Modified-Since · If-None-Match
이 필드를 응답에 붙이는 웹 서버 설정
nginx · Apache HTTP Server · mod_expires
이름이 겹치는 쿠키 속성과 그 이웃
쿠키 · Set-Cookie · Max-Age · RFC 6265 · 세션 · 사용자 에이전트
이것이 속하는 상위 분류
다른 이름: Expires 헤더 · Expires 필드