[414] [DFN[[CODE(HTTP)@en[[[POST]]]]]] [[メソッド]]は、[[対象資源]]に対して[[引数]]となるデータを引き渡して、処理を求めるものです。

[415] [[フォーム]]の[[提出]]などによって、 [[HTTP]]
を通じて[[鯖]]側の何らかのデータの追加、編集、削除、その他の操作を求めるために用いられます。

* 仕様書

[REFS[
- [412] '''[CITE@en[RFC 7231 - Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content]] ([TIME[2014-06-07 01:55:45 +09:00]] 版) <https://tools.ietf.org/html/rfc7231#section-4.3.3>'''
- [406] [CITE@en[RFC 7231 - Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content]] ([TIME[2014-06-07 01:55:45 +09:00]] 版) <https://tools.ietf.org/html/rfc7231#section-4.2.3>
- [6] [CITE@en[RFC 2324 - Hyper Text Coffee Pot Control Protocol (HTCPCP/1.0)]] ([TIME[2014-10-06 15:21:16 +09:00]] 版) <http://tools.ietf.org/html/rfc2324#section-2.1.1>
- [15] [CITE@en[RFC 2324 - Hyper Text Coffee Pot Control Protocol (HTCPCP/1.0)]] ([TIME[2014-10-06 15:21:16 +09:00]] 版) <http://tools.ietf.org/html/rfc2324#section-4>
- [16] [CITE@en[RFC 7168 - The Hyper Text Coffee Pot Control Protocol for Tea Efflux Appliances (HTCPCP-TEA)]] ([TIME[2014-10-12 17:41:43 +09:00]] 版) <http://tools.ietf.org/html/rfc7168#section-2.1>
- [17] [CITE@en[RFC 4918 - HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)]] ([TIME[2014-09-21 17:04:59 +09:00]] 版) <http://tools.ietf.org/html/rfc4918#section-7>
- [19] [CITE@en[RFC 4918 - HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)]] ([TIME[2014-09-21 17:04:59 +09:00]] 版) <http://tools.ietf.org/html/rfc4918#section-9.5>
- [405] [CITE@en[RFC 3875 - The Common Gateway Interface (CGI) Version 1.1]] ([TIME[2011-11-20 06:09:05 +09:00]] 版) <http://tools.ietf.org/html/rfc3875#section-4.3.2>
]REFS]

* 意味

[413] [CODE(HTTP)@en[[[POST]]]] [[メソッド]]は、[[要求]]に含まれる[[表現]]を[[対象資源]]がその自身の[RUBYB[意味]@en[semantics]]に従って処理することを要求するものです
[SRC[>>412]]。

[24] よく、単純な取得操作で[[副作用]]を持たない [CODE(HTTP)@en[[[GET]]]]
に対し、それ以外の何らかの変更操作一般を [CODE(HTTP)@en[[[POST]]]]
で行えると説明されます。

;; [25] 実際にどのような操作を行えるかは、その[[サーバー]]や[[資源]]の性質や実装に依存しており、
[[HTTP]] としては決められていません。[[資源]]を編集したり、削除したりできるかもしれませんし、
新しい[[資源]]を作成できるかもしれませんし、何もできないかもしれません。

[26] 本来 [CODE(HTTP)@en[[[GET]]]] で十分な時でも、 [[URL]]
が非常に長い (可能性がある) 場合に、 [CODE(HTTP)@en[[[POST]]]]
が代替として用いられることがあります。 [[要求URL]]
の長さに仕様上の上限はありませんが、実装上の制限を設けることは認められていますし、
実用上極めて長い [[URL]] は扱いにくいため、かわりに [[payload body]]
を使って[[引数]]を指定するというものです。

* 構文

[31] 
[[HTTPメソッド名]]は原則として[[大文字・小文字区別]]されますので、
[CODE[POST]]
はすべて[[大文字]]で書かなければなりません。

[32] 
ただし歴史的理由により、場合によって[[ASCII大文字・小文字不区別]]になることがあります。
(複雑なので常に[[大文字]]を使うのが安全です。)
[SEE[ [[HTTPメソッド]] ]]

-*-*-

[8] [CODE(HTTP)@en[[[POST]]]] [[要求]]の [[payload body]] には、処理の[[引数]]のような役割を果たすデータを含めるのが普通です。

[10] [[HTML]] の[[フォームの提出]]に使う場合は、次の [[MIME型]]を [[payload body]]
に含めます。
[FIG(short list)[
- [CODE(MIME)@en[[[application/x-www-form-urlencoded]]]]
- [CODE(MIME)@en[[[multipart/form-data]]]]
- [CODE(MIME)@en[[[text/plain]]]]
]FIG]

;; [[フォームの提出]]も参照。

[11] [[Web API]] ではしばしば [CODE(MIME)@en[[[application/json]]]] や
[[XML MIME型]]が使われます。

[14] [[HTCPCP]] の [CODE(HTTP)@en[[[POST]]]] [[要求]]では、 [[payload body]]
の [[MIME型]]は [CODE(MIME)@en[[[message/coffeepot]]]] でなければ[['''なりません''']] [SRC[>>15]]。 [[HTCPCP-TEA]] では [CODE(MIME)@en[[[message/teapot]]]]
を使います [SRC[>>16]]。

[23] それ以外の任意の [[MIME型]]を用いることもできますが、
[[相互運用性]]は低くなります。

[22] 仕様上必須とはされていませんが、 [CODE(HTTP)@en[[[Content-Length:]]]]
[[ヘッダー]]がなければ [CODE(HTTP)[[[411]]]] [[応答]]を返す実装が存在します。
[[クライアント]]は実用上 [CODE(HTTP)@en[[[Content-Length:]]]]
[[ヘッダー]]を指定する必要があります。

* 文脈

[9] [CODE(HTTP)@en[[[POST]]]] は [[HTML]] の[[フォームの提出]]に使える[[要求メソッド]]の1つです。
[[HTML]] では他に [CODE(HTTP)@en[[[GET]]]] も選べますが、
[[副作用]]を持つものは [CODE(HTTP)@en[[[POST]]]]、持たないものは [CODE(HTTP)@en[[[GET]]]]
と使い分けるのが普通です。

[12] [[Web API]] でも広く使われています。

[13] [[HTCPCP]] では [CODE(HTTP)@en[[[BREW]]]] と [CODE(HTTP)@en[[[POST]]]]
が等価 [SRC[>>6, >>16]] で、[[珈琲ポット]]への制御命令に使われています。ただし
[CODE(HTTP)@en[[[POST]]]] は[[非推奨]]とされています [SRC[>>6, >>16]]。

* 性質

[407] [CODE(HTTP)@en[[[POST]]]] は、[[キャッシュ可能]]な[[メソッド]]です [SRC[>>406]]。
ただし、[[キャッシュ可能]]なのは、明示的に[[新鮮度]]の情報を含む場合のみです [SRC[>>412]]。

;; >>419 参照。

;; [418] [CODE(HTTP)@en[[[POST]]]] の[[キャッシュ]]は、広くは実装されていません [SRC[>>412]]。

;; [2] 実際に [CODE(HTTP)@en[[[POST]]]] に対する[[応答]]を[[キャッシュ]]するべき場面がどれだけあるか、
[[キャッシュ]]を実装する価値があるかは甚だ疑問です。

;; [21] [CODE(HTTP)@en[[[PATCH]]]] [[メソッド]]も [CODE(HTTP)@en[[[POST]]]]
とほぼ同じ意味で[[キャッシュ可能]]です。 [CODE(HTTP)@en[[[GET]]]] や
[CODE(HTTP)@en[[[HEAD]]]] が[[キャッシュ可能]]であるというのとは若干意味が異なります。

[18] [[書き込みロック]]の適用対象となります [SRC[>>17]]。

* 処理

[416] [[起源鯖]]は、処理の結果によって適切な[[状態符号]]を選ぶことにより、
[[応答]]の意味を表します [SRC[>>412]]。

[417] [[起源鯖]]は、処理に成功して1つ以上の[[資源]]が作られた時には、
[CODE(HTTP)@en[[[201]]]] [[応答]]を送信する[['''べきです''']]。
[CODE(HTTP)@en[[[Location:]]]] [[ヘッダー]]に作成された主たる[[資源]]の [[URL]]
を含める[['''べきです''']]。[[表現]]は[[要求]]の状態と新しい[[資源]]への参照を説明したものとする[['''べきです''']]。
[SRC[>>412]]

[419] [[起源鯖]]は、 [CODE(HTTP)@en[[[POST]]]] への[[応答]]を[[キャッシュ]]させて以後の
[CODE(HTTP)@en[[[GET]]]] の処理で再利用できるようにしたい時は、
[CODE(HTTP)[[[200]]]] [[応答]]を送り、その [CODE(HTTP)@en[[[Content-Location:]]]]
[[ヘッダー]]に[[実効要求URL]]と同じ値を設定することができます [SRC[>>412]]。

[420] [[起源鯖]]は、処理の結果が既存の[[資源]]の[[表現]]と等価である時には、
その [[URL]] を [CODE(HTTP)@en[[[Location:]]]] [[ヘッダー]]に指定した
[CODE(HTTP)[[[303]]]] [[応答]]を送信することができます [SRC[>>412]]。

[421] 一般的には、 [[Webブラウザー]]で直接[[レンダリング]]することを想定して [[HTML]]
を返す場合には [CODE(HTTP)[[[302]]]] を返して[[リダイレクト]]することが多く、
[[JSON]] などを返す [[API]] の場合は [CODE(HTTP)[[[200]]]] を返すことが多いようです。

;; [4] [CODE(HTTP)[[[200]]]] を返すと [[Webブラウザー]]ではその [[payload body]]
が[[レンダリング]]されますが、その状態で[[利用者]]が[[再読み込み]]すると、
([[Webブラウザー]]が確認ダイアログを表示するのが現在では一般的になっていますが)
[CODE(HTTP)@en[[[POST]]]] [[要求]]が再送信されてしまいます。これは[[冪等]]ではなく、
普通は再投稿等の意図せぬ副作用を持ってしまうので、好ましくなく、
従って [CODE(HTTP)[[[302]]]] で[[リダイレクト]]するのが一般的になっています。
(簡単な完了メッセージなどは [CODE(HTTP)[[[302]]]] にせずに
[CODE(HTTP)[[[200]]]] でその場で返すこともあります。)

[422] 処理中にエラーが発生した場合には、その状況に応じて [CODE(HTTP)[[[400]]]],
[CODE(HTTP)[[[401]]]], [CODE(HTTP)[[[403]]]], [CODE(HTTP)[[[404]]]], [CODE(HTTP)[[[405]]]], [CODE(HTTP)[[[406]]]], [CODE(HTTP)[[[500]]]] などが返されることが多いですが、
[[状態符号]]を使い分けないアプリケーションでは、 [CODE(HTTP)[[[200]]]]
でエラーメッセージを含む [[HTML文書]]が返されることもよくあります。

[5] [[クライアント]]は [CODE(HTTP)@en[[[Prefer:]] [[return]]]]
によってどのような[[応答]]が返されることを望むか記述できます。
(しかし[[鯖]]はそれに従う義務はありません。)

[7] [[HTCPCP]] [[珈琲ポット]][[鯖]]は、 [CODE(HTTP)@en[[[POST]]]] を
[CODE(HTTP)@en[[[BREW]]]] と等価として扱わなければ[['''なりません''']] [SRC[>>6, >>16]]。

;; [CODE(HTTP)@en[[[BREW]]]] を参照。

[20] [[WebDAV]] [[コレクション]]でも通常の[[資源]]と同じように任意の処理を実行できます [SRC[>>19]]。

* 関連

[27] 宗教上の理由で [CODE(HTTP)@en[[[POST]]]] よりも
[CODE(HTTP)@en[[[PUT]]]] や [CODE(HTTP)@en[[[DELETE]]]] や
[CODE(HTTP)@en[[[PATCH]]]] を好む人もいます。

;; [28] これらを使い分ける必要があるわけではありません。
[[フォームの提出]]や[[プログラミング言語]]の[[ライブラリー]]等の対応状況を考えると、
すべて [CODE(HTTP)@en[[[POST]]]] で扱える方が便利です。

* 歴史

[FIG(quote)[
[FIGCAPTION[
[408] RFC 1945 (HTTP/1.0) 8.3; RFC 2068・2616 (HTTP/1.1) 9.5 POST
]FIGCAPTION]

> The POST method is used to request that the [DEL[[INS[{1945,2068}]] destination]] [INS[[INS[{2616}]] origin]] server accept
the entity enclosed in the request as [DEL[[INS[{1945,2068,2616}]] a new subordinate of]] [INS[[INS[{Errata}]] data to be processed by]] the
resource identified by the Request-URI in the Request-Line. POST is
designed to allow a uniform method to cover the following functions:

[CODE(HTTP)[POST]] 方式は、起源サーバーが要求に囲まれた[[実体]]を
[CODE(ABNF)[[[Request-Line]]]] の [CODE(ABNF)[[[Request-URI]]]]
で識別される[[資源]][DEL[の新しい付随物]][INS[で処理するデータ]]として受け入れることを要求するのに使います。
[CODE(HTTP)[POST]] は次の機能を覆う統一方式とできるように設計されています。

>
- [DEL[[INS[{1945,2068}]] o]] [INS[[INS[{2616}]] -]] Annotation of existing resources;
- [DEL[o]] [INS[-]] Posting a message to a bulletin board, newsgroup, mailing list,
or similar group of articles;
- [DEL[o]] [INS[-]] Providing a block of data, such as the result of submitting a
form [DEL[ [3] ]], to a data-handling process;
- [DEL[o]] [INS[-]] Extending a database through an append operation.

- 既存の資源に注釈を付ける
- [[掲示板]], [[ニュース組]], [[メイリング・リスト]]あるいは同様の記事の組へ投稿する
- [[フォーム]]で送信する結果のような、データの塊をデータ取扱い過程に提供する
- 付加操作を通じてデータベースを広げる

> The actual function performed by the POST method is determined by the
server and is usually dependent on the Request-URI. [DEL[[INS[{1945,2068,2616}]] The posted entity is subordinate to that URI in the same way that a file is subordinate to a directory containing it, a news article is subordinate to a newsgroup to which it is posted, or a record is subordinate to a database. [INS[{Errata で削除}]]]]

[CODE(HTTP)[POST}] 方式で行われる実際の機能はサーバーにより決定され、]]
通常 [CODE(ABNF)[Request-URI]] に依存します。[DEL[投稿された実体は、[[ファイル]]がそれを含む[[ディレクトリ]]に付随するとか、[[ニュース]]記事が投稿されたニュース組に付随するとか、[[記録]]がデータベースに藤生するのと同じように、その [[URI]] に付随します。]]

> [DEL[[INS[{1945}]] A successful POST does not require that the entity be created as a resource on the origin server or made accessible for future reference. That is, the]] [INS[The]]
action performed by the POST method might not result in a
resource that can be identified by a URI. In this case, either 200 [DEL[[INS[{1945}]] (ok)]] [INS[(OK)]] or 204 [DEL[[INS[{1945}]] (no content)]] [INS[(No Content)]]
is the appropriate response status, depending on whether or not the response includes an entity that describes the result.

;[DEL[[CODE(HTTP)[POST]] が成功したからといって、その実体が[[起源サーバー]]で[[資源]]として作られたり、生来の参照で接続可能となる必要はありません。つまり、]]
[CODE(HTTP)[POST]] 方式で行われる動作は結果として URI
で識別できる資源にならないかもしれません。
この場合、応答が結果を説明する実体を含むか否かによって、
[CODE(HTTP)[[[200]]]] (了解) または [CODE(HTTP)[[[204]]]] (無内容)
が適切な応答符号です。

> If a resource has been created on the origin server, the response [DEL[[INS[{1945}]] should]] [INS[SHOULD]] be 201 [DEL[[INS[{1945}]] (created)]] [INS[(Created)]] and contain an entity [DEL[[INS[{1945}]] (preferably of type "text/html")]]
which describes the status of the request and refers to the new resource[INS[, and a Location header (see section 14.30)]].

起源サーバーに資源が作られた場合は、応答は
[CODE(HTTP)[[[201]]]] (作成せし) とし、
要求の状態を説明して新しい資源を参照する実体[INS[と、 [CODE(HTTP)[[[Location]]]] 頭]]を含む'''べきです'''。

[DEL[

> A valid Content-Length is required on all HTTP/1.0 POST requests. An
HTTP/1.0 server should respond with a 400 (bad request) message if it
cannot determine the length of the request message's content.

すべての HTTP/1.0 [CODE(HTTP)[POST]] 要求で妥当な
[CODE(HTTP)[[[Content-Length]]]] が必要です。
HTTP/1.0 サーバーは、要求メッセージの内容の長さを決定できなければ
[CODE(HTTP)[[[400]]]] (悪い要求) メッセージで応答するべきです。

> Applications must not cache responses to a POST request because the
application has no way of knowing that the server would return an
equivalent response on some future request.

[[応用]]は、サーバーが将来の要求でも同等の応答を返すということを知る方法が応答にはないので、
[CODE(HTTP)[POST]] 要求への応答を[[キャッシュ]]してはなりません。
]DEL]

[INS[

> Responses to this method are not cach[INS[e]]able, unless the response
includes appropriate Cache-Control or Expires header fields. However,
the 303 (See Other) response can be used to direct the user agent to
retrieve a cach[INS[e]]able resource.

この方式への応答は、応答が適切な [CODE(HTTP)[[[Cache-Control]]]]
頭欄または [CODE(HTTP)[[[Expires]]]] 頭欄を含んでいない限り[[キャッシュ可能]]ではありません。
しかし、利用者エージェントがキャッシュ可能資源を取り出すように指向するために
[CODE(HTTP)[[[303]]]] (他を見よ) 応答を使えます。

> POST requests [DEL[must]] [INS[MUST]] obey the message transmission requirements set out
in section 8.2.

[CODE(HTTP)[POST]] 要求は8.2節のメッセージ転送要件に従わなければ'''なりません'''。

[INS[

> See section 15.1.3 for security considerations.

安全性について15.1.3節を参照。
]INS]
]INS]
]FIG]

[FIG(quote)[
[FIGCAPTION[
[409] Errata の変更事由
]FIGCAPTION]

> The description of POST was broadened over time, and is not clear.

[CODE(HTTP)[POST]] の説明は時間と共に広がり、明確ではありません。
]FIG]

[FIG(quote)[
[FIGCAPTION[
[410] RFC 2295 (HTTP 透過内容折衝) 12.2 Negotiation on transactions other than GET and HEAD
]FIGCAPTION]

[1]

> If a resource is transparently negotiable, this only has an impact on
the GET and HEAD transactions on the resource.  It is not possible
(under this specification) to do transparent content negotiation on
the direct result of a POST request.

資源が透過折衝可能であるときには、これはその資源の
[CODE(HTTP)[[[GET]]]] 及び [CODE(HTTP)[[[HEAD]]]]
の処理にのみ影響します。
(この仕様書では) [CODE(HTTP)[[[POST]]]] 要求の直接の結果について透過内容折衝することは不可能です。

> However, a POST request can return an unnegotiated 303 (See Other)
response which causes the user agent to do a GET request on a second
resource.  This second resource could then use transparent content
negotiation to return an appropriate final response.  The figure
below illustrates this.

しかし、 [CODE(HTTP)[POST]] 要求は利用者エージェントに2番目の資源に
[CODE(HTTP)[GET]] 要求を行わせる折衝しない [CODE(HTTP)[[[303]]]]
(他を見よ) 応答を返すことが出来ます。
この2番目の応答の方は透過内容折衝を使って適当な最終応答を返すことができます。
次の図はこれを図示しています。

>
[PRE[
      Server ______ proxy ______ proxy ______ user
      x.org         cache        cache        agent
        < -------------------------------------
        |     POST http://x.org/cgi/submit
        |     <form contents in request body>
        |
        -------------------------------------- >
              303 See Other                    |
              Location: http://x.org/result/OK |
                                               |
        < -------------------------------------
        |     GET http://x.org/result/OK
        |      small Accept- headers
        |
      able to choose on
      behalf of user agent
        |
         ------------------------------------- >
              choice response with             |
              ..result/OK.nl variant           |
                                           displays OK.nl
]PRE]

> See the HTTP/1.1 specification [1] for details on the 303 (See Other)
status code.  Note that this status code is not understood by some HTTP/1.0 clients.
]FIG]

[411] [CITE@en[RFC 7252 - The Constrained Application Protocol (CoAP)]]
( ([TIME[2014-06-27 00:59:37 +09:00]] 版))
<http://tools.ietf.org/html/rfc7252#section-5.8.2>

* メモ

[401] [CITE[POSTリクエストをリダイレクトするとGETされる?POSTされる? - はこべにっき#]] ([TIME[2009-07-08 20:09:48 +09:00]] 版) <http://d.hatena.ne.jp/hakobe932/20090707/1246985195>

[402] [CITE@en-US[Extra CRLF Character Is Added to a POST Request That Is Sent to an HTTP 1.1 Server]]
( ([TIME[2011-05-28 01:14:56 +09:00]] 版))
<http://support.microsoft.com/kb/823099/en-us>

[403] [CITE[Apache HTTP Server Project]]
( ([TIME[2011-05-28 00:58:55 +09:00]] 版))
<http://httpd.apache.org/docs/1.3/misc/known_client_problems.html#trailing-crlf>

[404] [CITE[Apache HTTP Server Project]]
( ([TIME[2011-05-28 00:58:55 +09:00]] 版))
<http://httpd.apache.org/docs/1.3/misc/known_client_problems.html#no-content-length>

[501] [CITE[tus resumable upload protocol]]
( ([TIME[2014-06-23 00:14:49 +09:00]] 版))
<http://tus.io/protocols/resumable-upload.html#6-1-3-1>

[29] [CITE@en[RFC 8144 - Use of the Prefer Header Field in Web Distributed Authoring and Versioning (WebDAV)]]
([TIME[2017-04-19 23:22:44 +09:00]])
<https://tools.ietf.org/html/rfc8144#section-3.1>

[30] [CITE@ja[Google ウェブマスター向け公式ブログ: より多くの有益なコンテンツを検索結果に: クローラが POST リクエストにも対応しました]]
([TIME[2018-01-18 11:25:54 +09:00]])
<https://webmaster-ja.googleblog.com/2012/01/post.html>