/
453.txt
165 lines (123 loc) · 10 KB
/
453.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
* 仕様書
[REFS[
- [7] '''[CITE@en[RFC 7232 - Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests]] ([TIME[2014-09-11 10:02:44 +09:00]] 版) <https://tools.ietf.org/html/rfc7232#section-4.1>'''
- [305] [CITE@en[RFC 7230 - Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing]] ([TIME[2014-06-07 01:59:35 +09:00]] 版) <https://tools.ietf.org/html/rfc7230#section-3.3>
- [3] [CITE@en[RFC 7232 - Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests]] ([TIME[2014-09-11 10:02:44 +09:00]] 版) <https://tools.ietf.org/html/rfc7232#section-3.2>
- [6] [CITE@en[RFC 7232 - Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests]] ([TIME[2014-09-11 10:02:44 +09:00]] 版) <https://tools.ietf.org/html/rfc7232#section-3.3>
]REFS]
* 意味
[8] [CODE(HTTP)[[[304]]]] は、[[条件付き要求]]である [CODE(HTTP)@en[[[GET]]]] や
[CODE(HTTP)@en[[[HEAD]]]] の[[要求]]を受信した際に、条件が[[偽]]でなかったなら
[CODE(HTTP)[[[200]]]] [[応答]]を送信していたであろうことを示す[[状態符号]]です [SRC[>>7]]。
[9] これはすなわち、[[クライアント]]が既に[[対象資源]]の[[妥当]]な[[表現]]を持っているため、
再度あえて転送する必要はなく、従って[[クライアント]]が保持している[[表現]]が
[CODE(HTTP)[[[200]]]] [[応答]]の [[payload]] だったかのように[[リダイレクト]]するものです。
[SRC[>>7]]
;; [10] これは一般的な意味の [[HTTPリダイレクト]]とは異なりますが、
[[HTTP]] 仕様上は[[クライアント]]の保持する[[キャッシュ]]への
「[[リダイレクト]]」に分類されています。
* 構文
[11] [CODE(HTTP)[[[304]]]] [[応答]]を[[生成]]する[[鯖]]は、
[CODE(HTTP)[[[200]]]] [[応答]]だったなら送られるであろう次の[[ヘッダー]]を同様に[[生成]]しなければ[['''なりません''']]
[SRC[>>7]]。
[FIG(short list)[
- [CODE(HTTP)@en[[[Cache-Control:]]]]
- [CODE(HTTP)@en[[[Content-Location:]]]]
- [CODE(HTTP)@en[[[Date:]]]]
- [CODE(HTTP)@en[[[ETag:]]]]
- [CODE(HTTP)@en[[[Expires:]]]]
- [CODE(HTTP)@en[[[Vary:]]]]
]FIG]
;; [17] [CODE(HTTP)[[[200]]]] の時送らないものは、送る必要はありません。
[12] [[送信者]]は、 >>11 以外の[[表現メタデータ]]は[[キャッシュ]]の更新の案内のためのものを除き、
[[生成]]する[['''べきではありません''']] [SRC[>>7]]。
[EG[
[13] 例えば [CODE(HTTP)@en[[[Last-Modified:]]]] は [CODE(HTTP)@en[[[ETag:]]]]
がない場合に有用かもしれません [SRC[>>7]]。
]EG]
;; [14] ... というような曖昧な規定よりも、適切なもの、不適切なもののリストを仕様書に含めていただけるた方が有用だと思うのですが...
他に該当しそうなものは [CODE(HTTP)@en[[[Pragma:]]]] でしょうか。
[306] [CODE(HTTP)[[[304]]]] [[応答]]は、[[メッセージ本体]]を持ちません [SRC[>>305, >>7]]。
* 文脈
[4] [CODE(HTTP)@en[[[If-None-Match:]]]] の条件を満たさない場合で[[要求メソッド]]が
[CODE(HTTP)@en[[[GET]]]] か [CODE(HTTP)@en[[[HEAD]]]] の場合には、
[CODE(HTTP)[[[304]]]] [[応答]]を返すことができます [SRC[>>3]]。
[5] [CODE(HTTP)@en[[[If-Modified-Since:]]]] の条件を満たさない場合には、
[CODE(HTTP)[[[304]]]] [[応答]]を返すことができます [SRC[>>6]]。
* 処理モデル
[15] [[外向き]]の[[クライアント]]が[[条件付き要求]]を作成した場合、
例えば[[キャッシュ]]を持つ[[利用者エージェント]]が[[共有串]]に[[条件付きGET]]
を送信した場合には、[[串]]は [CODE(HTTP)[[[304]]]]
[[応答]]をその[[クライアント]]に[[転送]]する[['''べきです''']]
[SRC[>>7]]。
;; [16] [[串]]は自身の[[キャッシュ]]を有する場合でも、
[[条件付き要求]]だった場合には [CODE(HTTP)[[[304]]]] をそのまま[[転送]]するべきということです。
そうではなく[[串]]が元の[[要求]]を[[条件付き要求]]に書き換えていた場合には、
[[串]]は [CODE(HTTP)[[[200]]]] [[応答]]に書き換える必要が生じます。
* 歴史
[FIG(quote)[
[FIGCAPTION[
[307] RFC 1945 (HTTP/1.0); RFC 2068・2616 (HTTP/1.1) 10.3.5 304 Not Modified
]FIGCAPTION]
> If the client has performed a conditional GET request and access is
allowed, but the document has not been modified [DEL[[DEL[{1945}]] since the date and time specified in the If-Modified-Since field]],
the server [DEL[[DEL[{1945}]] must]] [INS[[DEL[{2068}]] SHOULD]] respond with this status code [DEL[[DEL[{1945}]] and not send an Entity-Body to the client]]. [INS[[DEL[{2068,2616}]] The [INS[304]] response MUST NOT contain a message-body[INS[, [INS[{2616}]] and thus is always terminated by the first empty line after the header fields]].]] [DEL[[DEL[{1945}]] Header fields contained in the response should only include information which is relevant to cache managers or which may have changed independently of the entity's Last-Modified date. Examples of relevant header fields include: Date, Server, and Expires. A cache should update its cached entity to reflect any new field values given in the 304 response.]]
クライアントが条件付き [CODE(HTTP)[[[GET]]]] 要求を行い、接続は認められたものの、
文書は[DEL[[CODE(HTTP)[[[If-Modified-Since]]]] 欄に指定されて日付・時刻から]]修正されていないなら、
サーバーはこの状態符号で応答[DEL[してはならず、クライアントに [CODE(ABNF)[[[Entity-Body]]]] を送信してはなりません。]][INS[する'''べき'''です。]][INS[[CODE(HTTP)[304]] 応答は [CODE(ABNF)[[[message-body]]]] を含んでいては'''ならりません'''[INS[で、従って頭欄の後の最初の空行で常に終端します]]。]][DEL[応答中に含まれる頭欄はキャッシュ管理器に関係する情報又は実体の [CODE(HTTP)[[[Last-Modified]]]] 日付に独立して変わったかもしれない情報のみを含むべきです。関係する頭欄の例 : [CODE(HTTP)[[[Date]]]], [CODE(HTTP)[[[Server]]]], [CODE(HTTP)[[[Expires]]]]。キャッシュは、キャッシュした実体が [CODE(HTTP)[304]] 応答で与えられた新しい欄値を反映するように更新するべきです。]]
[INS[
> [INS[{2068,2616}]] The response MUST include the following header fields:
- Date[INS[, unless its omission is required by section 14.18.1]]
応答は次の頭欄を含まなければ'''なりません''':
- [CODE(HTTP)[Date]] [INS[省略が義務付けられている場合を除く]]
[INS[
> [INS[{2616}]] If a clockless origin server obeys these rules, and proxies and
clients add their own Date to any response received without one (as
already specified by [RFC 2068], section 14.19), caches will operate correctly.
時計のない起源サーバーはこれらの規則に従い、
串及びクライアントが自身の [CODE(HTTP)[Date]] を [CODE(HTTP)[Date]]
なしで受信した応答に付け加えれば、
キャッシュは正しく処理されます。
]INS]
>
- ETag and/or Content-Location, if the header would have been sent in
a 200 response to the same request
- Expires, Cache-Control, and/or Vary, if the field-value might
differ from that sent in any previous response for the same variant
- [CODE(HTTP)[ETag]] [[及び/又は]] [CODE(HTTP)[[[Content-Location]]]]
その頭が同じ要求に対する [CODE(HTTP)[[[200]]]] 応答でも送られるであろうなら
- [CODE(HTTP)[[[Expires]]]], [CODE(HTTP)[[[Cache-Control]]]]
及び/又は [CODE(HTTP)[[[Vary]]]]
欄値が同じ変種に対する以前の応答で送られたものと異なるかもしれないなら
> If the conditional GET used a strong cache validator (see section
13.3.3), the response SHOULD NOT include other entity-headers.
Otherwise (i.e., the conditional GET used a weak validator), the
response MUST NOT include other entity-headers; this prevents
inconsistencies between cached entity-bodies and updated headers.
条件付き [CODE(HTTP)[GET]] が[[強いキャッシュ検証]]を使っているなら、
応答は他の実体頭欄を含む'''べきではありません'''。
そうでなければ、 (つまり条件付き [CODE(HTTP)[GET]] が弱い検証を使っているなら、)
応答は他の実体頭欄を含んでは'''なりません'''。
これによってキャッシュされている実体本体と更新された頭の不一致を防ぐことができます。
> If a 304 response indicates an entity not currently cached, then the
cache MUST disregard the response and repeat the request without the conditional.
[CODE(HTTP)[304]] 応答が実体は現在キャッシュされていないことを示すなら、
その時はキャッシュは応答を捨てて条件付きでない要求を繰り返さなければ'''なりません'''。
> If a cache uses a received 304 response to update a cache entry, the
cache MUST update the entry to reflect any new field values given in the response.
キャッシュが受信した [CODE(HTTP)[304]] 応答を使ってキャッシュ項目を更新するなら、
キャッシュは応答中に与えられた新しい欄値を反映して実体を更新しなければ'''なりません'''。
[DEL[
> [INS[{2068}]] The 304 response MUST NOT include a message-body, and thus is always
terminated by the first empty line after the header fields.
[CODE(HTTP)[304]] 応答は [CODE(ABNF)[[[message-body]]]] を含んでは'''ならず'''、
従って常に頭欄の後の最小の空行で終端します。
]DEL]
]INS]
]FIG]
* メモ
[1] この応答符号、明らかに意味が他の [CODE(HTTP)[[[3xx]]]]
と違いますよねえ。。。
[2]
[CODE(DOMi)@en[[[XMLHttpRequest]]]]で[CODE(DOMa)@en[[[statusCode]]]]が[CODE(HTTP)@en[[[304]]]]になることがよくありますが、それを考慮していない使用例が多過ぎのような気がします。。。
([[名無しさん]] [sage] [WEAK[2006-01-01 05:59:22 +00:00]])