2022-07-28(Thu)追記: 記述に不足を認めたのであらためて改稿版を公開しました。そちらをご覧いただければ幸いです。
ブラウザで動くJavaScriptから、GETメソッドを指定したHTTPリクエストでメッセージボディを指定できないのはなぜか?という話題を見かけまして、指定できないのは知っていましたが理由はたしかめてなかったので追いかけてみました。
TL;DR
- HTTPの仕様としては規定されず、実装依存で拒否される可能性ありとの記述あり
- ブラウザのクライアントでは指定不可
HTTPの仕様としては?
HTTP/1.0を規定するRFC 1945、HTTP/1.1を規定していたRFC 2068およびRFC 2616には言及はありません。改訂版のRFC 7231は4.3.1に次の記述があります:
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リクエストにボディを指定できないのはブラウザ=クライアントが認めないから」ということでよいかと思います。
以上、お勉強の時間でした。