本稿はHTTP GETリクエストにボディを指定できないのはなぜか?(初版)の改稿版です。変更点は稿末の「改稿の詳細」をご覧ください。
ブラウザで動くJavaScriptから、GETメソッドを指定したHTTPリクエストでメッセージボディを指定できないのはなぜか?という話題を見かけまして、指定できないのは知っていましたが理由はたしかめてなかったので追いかけてみました。
TL;DR
- HTTPの仕様としては規定されず、実装依存で拒否される可能性ありとの記述あり
- ブラウザのクライアントでは指定不可
HTTPの仕様としては?
HTTP/1.0を規定するRFC 1945、HTTP/1.1を規定していたRFCのうちRFC 2068には言及はありません。
HTTP/1.1を規定していたもう一つのRFC、RFC 2616は4.3 Message Bodyに次の記述があります:
A message-body MUST NOT be included in a request if the specification of the request method ([section 5.1.1](https://datatracker.ietf.org/doc/html/rfc2616#section-5.1.1)) does not allow sending an entity-body in requests. A server SHOULD read and forward a message-body on any request; if the request method does not include defined semantics for an entity-body, then the message-body SHOULD be ignored when handling the request.
クライアントはリクエストメソッドの仕様がボディ送信を許可しないときはボディを送信してはならない、サーバーはあらゆるメソッドのボディを読み込むべきであるがボディのセマンティクスを定義しないリクエストメソッドのボディは無視すべきである、としています。
改訂版のRFC 7231ではリクエストメソッドの定義がメソッドごとに切り分けられます。4.3.1 GETの記述は次のとおり:
A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request.
定義されたセマンティクスなし、一部の既存実装が要求を拒否する可能性あり、としています。なので仕様としてはあずかりしらないということですね。HTTPサーバーによっては使えるかもしれない、と。
ブラウザのクライアントの仕様は?
ブラウザによるHTTPアクセスは、ブラウザ自身によるものの他はXMLHttpRequestまたはfetch APIを利用します。
XMLHttpRequest Standardは3.5.6で次が規定されています。
3. If this’s request method is `GET` or `HEAD`, then set body to null.
Fetch Standardは5.4. Request classに次の記述が。
35. If either init["body"] exists and is non-null or inputBody is non-null, and request’s method is `GET` or `HEAD`, then throw a TypeError.
つまりどちらを利用しても指定できません(一方は強制的に null
設定、一方はエラーあつかい)。
まとめ
Web技術は実装が先行して仕様が後追いすることが多かったので、過去においてはGETメソッドでのボディ指定も可能だったかもしれません。しかし現在は仕様作成が実装に先行、または並走することが多く、仕様も明確化されているので、解釈が揺れる余地はありません。「HTTP GETリクエストにボディを指定できないのはブラウザ=クライアントが認めないから」ということでよいかと思います。
改稿の詳細
初版では「HTTPの仕様としては?」でRFC 2616には言及なしとしていました。しかし最近渋川よしき著の『Real World HTTP ミニ版』を手にしたところ、「1章 HTTP/1.0の世界 : 基本となる4つの要素」の「1.8.1 GETリクエスト時のボディ」が本稿と重なるトピックをあつかっており、その中でRFC 2616での記述に言及されていました。同書の説明は次のとおり:
「サーバーはメッセージボディを読み込める必要はあるが、リクエストされたメソッドがボディのセマンティクスを定めていない場合は、リクエストの処理時にメッセージボディは無視されるべき(SHOULD be ignored)」と書かれています。
あらためてRFC 2616を閲覧したところ記載内容を確認できたので、その結果を反映させるべく改稿した次第です。著者の渋川よしき氏に感謝いたします。
なお『Real World HTTP ミニ版』はHTTPにまつわるトピックがコンパクトにまとめられた良書です。太っ腹なことに無料で入手できますので、Webにかかわりながら体系的な学習に手のまわらない方にはご一読をお勧めします。
以上、あらためてお勉強の時間でした。