[49] [DFN[[CODE(HTTP)@en[[[Prefer:]]]]]] [[ヘッダー]]は、[[要求]]の処理方法に関する[[クライアント]]の好みを示すものです [SRC[>>7]]。

* 仕様書

[REFS[
- [7] '''[CITE@en[RFC 7240 - Prefer Header for HTTP]]
( ([TIME[2014-06-07 01:59:37 +09:00]] 版))
<http://tools.ietf.org/html/rfc7240>'''
- [50] [CITE[Hypertext Transfer Protocol (HTTP) Parameters]] ([TIME[2014-06-13 18:52:05 +09:00]] 版) <http://www.iana.org/assignments/http-parameters/http-parameters.xhtml#preferences>
]REFS]

* 意味

[15] [CODE(HTTP)@en[[[Prefer:]]]] [[ヘッダー]]は、
[[クライアント]]が[[鯖]]の特定の動作を[RUBYB[好んでいる]@en[prefer]]こと、
しかしそれは[[要求]]の成功には必須ではないことを示すために使います [SRC[>>7]]。

[EG[
[8] [CODE(HTTP)@en[[[PUT]]]] により[[資源]]を編集した後に、
変更後の完全な[[表現]]を[[応答]]として得たいこともあれば、
操作が成功したことのみの最低限の[[応答]]を得たいこともあります [SRC[>>7]]。
]EG]

[EG[
[9] [[鯖]]は、技術的に[[非妥当]]だったり誤っていたりするものの理解はできる[[要求]]をどう処理するか決めなければならないことがあります。
[[鯖]]は誤りがあっても[[要求]]を処理できるかもしれませんが、
[[アプリケーション]]の要件と[[要求]]の性質によってはそれが好ましかったり、
好ましくなかったりするかもしれません。 [SRC[>>7]]
]EG]

[42] [CODE(HTTP)@en[[[Prefer:]]]] は[[内容折衝]]の仕組みとして使う[['''べきではありません''']]
[SRC[>>7]]。

* 構文

[16] [CODE(HTTP)@en[[[Prefer:]]]] [[ヘッダー]]の値は、1つ以上の「好み」
の[[リスト]] ([CODE(HTTP)[#]]) です [SRC[>>7]]。

[FIG(railroad)[
= 好み
= *
== [[OWS]]
== [CODE(HTTP)[[[,]]]]
== [[OWS]]
== 好み
]FIG]

[19] 好みは、[[好み字句]]に、省略可能な値と、0個以上の[[引数]]を続けたものです。
値を指定する場合は、 [CODE(HTTP)[[[=]]]] を[[字句]]と値の間に置きます。
また各[[引数]]の前には [CODE(HTTP)[[[;]]]] を置きます。 [SRC[>>7]]

[29] [[好み字句]]は、[[字句]]です。[[大文字・小文字不区別]]です。 [SRC[>>7]]

[FIG(railroad)[
= [[字句]]
= ?
== [CODE(HTTP)[[[=]]]]
== |
=== [[字句]]
=== [[引用文字列]]
= *
== [[OWS]]
== [CODE(HTTP)[[[;]]]]
== ?
=== [[OWS]]
=== [[引数]]
]FIG]

[35] 同名の[[好み字句]]を複数回指定する[['''べきではありません''']] [SRC[>>7]]。

;; [36] なぜ [['''MUST''']] でないのか謎です。

[37] 別名の[[好み字句]]の順序は意味を持ちません [SRC[>>7]]。

[24] [[引数]]は、名前か、名前と値を [CODE(HTTP)[[[=]]]] で連結したものです [SRC[>>7]]。

[26] [[引数]]の名前は、[[字句]]です。[[大文字・小文字不区別]]です。 [SRC[>>7]]

[FIG(railroad)[
= [[字句]]
= ?
== [CODE(HTTP)[[[=]]]]
== |
=== [[字句]]
=== [[引用文字列]]
]FIG]

[20] ただし[[引数]]のかわりに[[空文字列]]とすることができます [SRC[>>7]]。

[30] [[引数]]の意味は[[好み字句]]に依存します。[[引数]]の順序は意味を持ちません。 [SRC[>>7]]

;; [38] 同名の[[引数]]の処理には [[RFC]] は言及していないようです。

[21] [CODE(HTTP)[[[;]]]] の前後には [[OWS]] を挿入できます。また [CODE(HTTP)[[[=]]]]
の前後には [[BWS]] があります。 [SRC[>>7]]

[22] 値は[[字句]]または[[引用文字列]]です。

;; [23] [[RFC 7240]] は [[RFC 7230]] の [CODE(ABNF)@en[[[word]]]]
を参照していますが、そのような定義は [[RFC 7230]] にはありません。文脈から >>22
のように推測されます。

[46] [[字句]]と[[引用文字列]]のどちらの構文を使っても構わず、
どちらも同じ意味と思われますが、明記はされていません。また[[好み字句]]それぞれの構文の定義で値が[[字句]]または[[引用文字列]]のどちらかの構文だけが示されていることがありますが、
[[HTTP]] の仕様では歴史的にどちらでも構わないものと (行間から) 解釈されています。

;; [47] 2014年にもなって未だに行間を読まないといけない仕様書が新たに出版されるとは驚きですが...

[27] [[好み字句]]についても[[引数]]についても、値がないものと、
[[空文字列]]の値は同じです [SRC[>>7]]。

[EG[
[28] 次の3つの[[ヘッダー]]は同じ意味です [SRC[>>7]]。

[PRE(HTTP code)[
Prefer: foo; bar
Prefer: foo; bar=""
Prefer: foo=""; bar
]PRE]
]EG]

;; [55] これが正しく実装されているかどうかは怪しいところです。[[要求ヘッダー]]の場合、
解釈するのは[[串]]、[[鯖]]、[[WAF]] などの[[ライブラリー]]、個々の
[[Webアプリケーション]]のいずれにせよ多数あり、[[相互運用性]]が高い状態を維持するのは困難そうです。
[CODE(HTTP)@en[[[Prefer: safe]]]] を理解できる[[Webサービス]]が
[CODE(HTTP)@en[[[Prefer:]] [[safe]]=""]] も理解できるかは大変怪しいと思われます。
(なぜ敢えて[[相互運用性]]が低くなる危険を犯してまでこんな複雑な構文と意味を規定したのでしょうか...)

* 文脈

[17] この[[ヘッダー]]は[[要求]]で使います。

[18] この[[ヘッダー]]は複数指定できます。

* 処理

[25] [[鯖]]は、[[好み字句]]を認識できない場合や従えない場合には、[[誤り]]を通知するのではなく、
当該[[字句]]を無視して処理を継続しなければ[['''なりません''']] [SRC[>>7]]。

;; [34] [CODE(HTTP)@en[[[Expect:]]]] の場合は未対応なら [CODE(HTTP)[[[417]]]]
を返すことになっていますが、 [CODE(HTTP)@en[[[Prefer:]]]]
ではそのような処理は認められていません。

[39] [[鯖]]は同名の[[好み字句]]が複数回指定されていれば、[[誤り]]通知その他の通常と異なる処理をすることなく、最初のもの以外は無視する[['''べきです''']] [SRC[>>7]]。

;; [40] なぜか [['''MUST''']] ではないようです。

[31] [[串]]は、 [CODE(HTTP)@en[[[Connection:]]]] で明示されない限り、
[CODE(HTTP)@en[[[Prefer:]]]] を[[転送]]しなければ[['''なりません''']] [SRC[>>7]]。

[32] [[串]]は[[起源鯖]]とは別に [CODE(HTTP)@en[[[Prefer:]]]] を受けて処理しても構いません
[SRC[>>7]]。

;; 例えば [CODE(HTTP)@en[[[respond-async]]]] を参照。

;; [33] しかしその場合に [CODE(HTTP)@en[[[Prefer:]]]] を削除しても良いとはされていないようです。

[41] [[応答]]の[[キャッシュ]]に影響を及ぼす形で [CODE(HTTP)@en[[[Prefer:]]]]
を使わないよう注意することが[RUBYB[すすめられています]@en[urged]] [SRC[>>7]]。
[CODE(HTTP)@en[[[Prefer:]]]] の指定 (またはその欠如) が[[応答]]の[[キャッシュ]]に影響を及ぼすなら、
[CODE(HTTP)@en[[[Vary:]] [[Prefer]]]] または [CODE(HTTP)@en[[[Prefer:]] *]]
を指定しなければ[['''なりません''']] [SRC[>>7]]。

;; [60] 実際 [CODE(HTTP)@en[[[Upgrade-Insecure-Requests:]]]] は当初
[CODE(HTTP)@en[[[Prefer:]]]] を使うことを計画していましたが、
撤回されました ([CODE(HTTP)@en[[[Upgrade-Insecure-Requests:]]]] 参照)。
しかしそんな具合では、[[HTTPキャッシュ]]が使われ得る場面で [CODE(HTTP)@en[[[Prefer:]]]]
[[ヘッダー]]はほとんど使いものにならないということになりますね。

* 好み字句

[44] [CODE(HTTP)@en[[[Prefer:]]]] [[ヘッダー]]で指定する[[リスト]]項目それぞれの[[字句]]は[DFN[[RUBYB[[[好み字句]]]@en[preference token]]]] [SRC[>>7]]
と呼ばれています。またそれぞれの項目 (あるいは[[好み字句]]によって表される概念) のことは[DFN[[RUBYB[好み]@en[preference]]]] [SRC[>>7]] と呼ばれています。

[48] [[好み字句]]としては次のようなものが定義されています。
[FIG(short list)[
- [CODE(HTTP)@en[[[contents-of-related]]]]
- [CODE(HTTP)@en[[[depth-noroot]]]]
- [CODE(HTTP)@en[[[handling]]]]
- [CODE(HTTP)@en[[[https]]]]
- [CODE(HTTP)@en[[[odata.allow-entityreferences]]]]
- [CODE(HTTP)@en[[[odata.callback]]]]
- [CODE(HTTP)@en[[[odata.continue-on-error]]]]
- [CODE(HTTP)@en[[[odata.include-annotations]]]]
- [CODE(HTTP)@en[[[odata.maxpagesize]]]]
- [CODE(HTTP)@en[[[odata.track-changes]]]]
- [CODE(HTTP)@en[[[respond-async]]]]
- [CODE(HTTP)@en[[[return]]]]
- [CODE(HTTP)@en[[[return-content]]]]
- [CODE(HTTP)@en[[[return-no-content]]]]
- [CODE(HTTP)@en[[[safe]]]]
- [CODE(HTTP)@en[[[tls]]]]
- [CODE(HTTP)@en[wait][Prefer: wait]]
]FIG]

;; [54] 現時点で広く実装されているのは [CODE(HTTP)@en[[[Prefer: safe]]]]
のみです。 [TIME[2014-10-27T10:06:02.600Z]]

[45] [[好み字句]]には [[IANA登録簿]]があります [SRC[>>7, >>50]]。

[43] [[RFC 7240]] には [CODE(HTTP)[priority]] という架空の[[好み字句]]の例 [SRC[>>7]]
も示されています。

[58] >>57 に [[JSON]] 形式の[[好み字句]]一覧があります。
[REFS[
- [57] [CITE@en[data-web-defs/headers.txt at master · manakai/data-web-defs]] ([TIME[2014-10-28 05:29:17 +09:00]] 版) <https://github.com/manakai/data-web-defs/blob/master/doc/headers.txt>
]REFS]

[51] [[引数]]については各[[好み字句]]の項を参照。


[64] 
[CITE@en[Tables and Views — PostgREST devel documentation]], [TIME[2025-09-19T18:49:54.000Z]], [TIME[2025-12-02T08:49:21.207Z]] <https://docs.postgrest.org/en/latest/references/api/tables_views.html>



* 歴史

[62] [[RFC 723[VAR[x]]]] と同時に出版された [DFN[RFC 7240]] により導入されました。

[REFS[
- [2] [CITE@en[draft-snell-http-prefer-18 - Prefer Header for HTTP]]
( ([TIME[2013-10-27 07:56:15 +09:00]] 版))
<http://tools.ietf.org/html/draft-snell-http-prefer-18>
- [5] [CITE@en[RFC 7240 - Prefer Header for HTTP]]
( ([TIME[2014-06-07 01:59:37 +09:00]] 版))
<http://tools.ietf.org/html/rfc7240>
]REFS]

[52] [[OData]] は [CODE(HTTP)@en[[[Prefer:]]]] を[[プロトコル]]に組み込んでいます。

[53] ただし [[OData]] が独自に追加した[[好み]]は現時点で [[IANA]]
に登録されていません。 [TIME[2014-10-27T09:53:00.200Z]]

[REFS[
- [6] [CITE@en[2.2.5.9 Prefer]]
( ([TIME[2014-07-25 04:45:16 +09:00]] 版))
<http://msdn.microsoft.com/en-us/library/hh537533.aspx>
- [1] [CITE[OData Version 4.0 Part 1: Protocol]]
( ([TIME[2013-08-14 16:00:00 +09:00]] 版))
<http://docs.oasis-open.org/odata/odata/v4.0/cs01/part1-protocol/odata-v4.0-cs01-part1-protocol.html>
]REFS]

[4] [[LDP]] も [CODE(HTTP)@en[[[Prefer:]]]] を採用していますが、やはり独自に拡張しています。

[REFS[
- [3] [CITE@en[Linked Data Platform 1.0]]
( ([TIME[2014-03-05 18:42:42 +09:00]] 版))
<http://www.w3.org/TR/2014/WD-ldp-20140311/#h3_prefer-parameters>
]REFS]

* 実装

[61] [CODE(HTTP)@en[[[Prefer:Safe]]]] は [[Webブラウザー]]や [[Webアプリケーション]]で多数の実装例があります。
その他の機能が実装されているのかは不明です。

* 関連

[10] [CODE(HTTP)@en[[[Expect:]]]] [[ヘッダー]]の元々の定義も似たようなものでしたが、
[CODE(HTTP)@en[[[Expect:]]]] の場合すべての[[中間器]]と[[起源鯖]]がすべての「期待」
に対応していなければ拒絶しなければならないことになっており、
対応していてもいなくても良い[[クライアント]]の「好み」には相応しくないとして
[CODE(HTTP)@en[[[Prefer:]]]] が別途追加されました [SRC[>>7]]。
[[鯖]]は [CODE(HTTP)@en[[[Prefer:]]]] で指定された「好み」を無視することができます [SRC[>>7]]。

[14] [CODE(HTTP)@en[[[Opt:]]]] [[ヘッダー]]も似たような要件で追加されたようですが、
[[名前空間]]により間接的に要望を記述するものとなっていますので、
直接指定する [CODE(HTTP)@en[[[Prefer:]]]] とは異なっています。

;; [CODE(HTTP)@en[[[Opt:]]]] が[[名前空間]]と複数の[[ヘッダー]]を使って記述していたものを
[CODE(HTTP)@en[[[Prefer:]]]] は単一の[[ヘッダー]]で記述する形に改めたとも解釈できます。

[11] [[要求URL]] の [[query]] に「好み」を指定することもできますが、
[[URL]] を変更すると[[キャッシュ]]に悪影響があるなど相応しくないとして、
[CODE(HTTP)@en[[[Prefer:]]]] が別途追加されました [SRC[>>7]]。

[12] [CODE(HTTP)@en[[[Prefer:]]]] で指定する値として規定・提案されているもののうちのいくつかは、
[[URL]] の [[query]] や [CODE(HTTP)@en[[[POST]]]] 時の [CODE(MIME)@en[[[application/x-www-form-urlencoded]]]]
や [CODE(MIME)@en[[[multipart/form-data]]]] や [CODE(MIME)@en[[[application/json]]]]
などの [[payload body]] に ([[アプリケーション]]依存の方法で) 指定するので十分な気がしますが・・・。

[13] あるいは [CODE(HTTP)@en[[[Prefer:]]]] [[ヘッダー]]にまとめずとも、
用途ごとにそれぞれ個別の[[ヘッダー]]とした方が処理もしやすそうなものがいくつかありますが・・・。

[56] [[JSON Home Document]] では、 [CODE@en[[[accept-prefer]]]] により[[鯖]]が対応できる[[好み字句]]を表明できます。

[418] [CITE@ja[Create Table]]
( ([TIME[2014-11-03 07:44:33 +09:00]] 版))
<http://msdn.microsoft.com/ja-jp/library/azure/dd135729.aspx>

[FIG(quote)[
[FIGCAPTION[
[59] [CITE@en[Upgrade Insecure Requests]]
([TIME[2015-10-07 03:24:10 +09:00]] 版)
<https://w3c.github.io/webappsec-upgrade-insecure-requests/#feature-detect>
]FIGCAPTION]

> Note: Though the Upgrade-Insecure-Requests header expresses a preference, sending it via the existing Prefer header is problematic, as we expect the response from the server to use it as part of the cache key. Vary: Prefer is too broad, as discussed in w3/webappsec#216.

]FIG]


[FIG(quote)[
[FIGCAPTION[
[63] [CITE@en[Web Annotation Protocol]]
([TIME[2017-02-24 02:14:26 +09:00]])
<https://w3c.github.io/web-annotation/protocol/wd/#h-annotation-pages>
]FIGCAPTION]

> The client should not send the Prefer header when requesting the Page, as it has already been taken into account when requesting the Collection.

]FIG]
