ここから先はミラーです。
HTTPのGETメソッドにはURI(URL)の長さ制限(実装上の制限)があることもあり、WEBアプリetcの検索機能では、検索条件が多く、クエリパラメータが極端に長くなる場合、リクエストボディにデータを含められる POST メソッドが利用されてきました。
検索機能にPOSTメソッドを用いるのは、HTTPのセマンティクス(意味論)的に問題があるので、IETFのHTTPワーキンググループにQUERYメソッドが提案されています。
レガシー・ブラウザでは、URI(URL)の長さ制限が2000文字程度と短く、検索条件が多く、クエリパラメータが長くなる場合、エラーとなっていましたが、モダン・ブラウザでは制限が緩和され、8000バイト(8KB、2,000〜4,000文字)程度となっています。
検索機能にPOSTメソッドを用いる必然性は、昔より低下しています。
今こそ、GETで検索を見直すべきときではないでしょうか?
POSTで検索
技術的には可能ですが、HTTPのセマンティクス(意味論)的には問題があるので、検索条件が多く、クエリパラメータが極端に長くなることが実際のユースケースとして(普通に)ありえる場合に限り、採用すべきです。
今どき?GETで検索
検索条件毎にクエリ・パラメータを渡すのではなく、検索条件を一まとめにしてJSONの形で1つのクエリ・パラメータとしてセットすることをオススメします。
検索条件を一まとめにすることで、バイト長チェックが簡単になり、入力エラーにして極端に長いクエリーパラメータを回避することが容易になります。
JSONの形で扱うことで、サーバーサイドでの取り回しも楽になります。
また、将来的にHTTPのQUERYメソッドがRFCとして承認され実装された際には、QUERYメソッドのリクエスト・ボディにパラメータとして検索条件を一まとめにしたJSONをセットするだけで、サーバーサイドのロジックをほとんど修正することなく移行を完了できます。
QUERYメソッドのリクエスト・ボディに検索条件を一まとめにしたJSONをセットすることも可能ですが、
リクエスト・パラメータ→リクエスト・ボディした場合には、サーバーサイドの修正が若干?必要になります。
実装例(Rails)
モノリス
バックエンド(json api)
今でき?POSTで検索
検索条件毎にリクエスト・ボディのパラメータとして渡すのではなく、検索条件を一まとめにしてJSONの形で1つのパラメータとして or リクエスト・ボディーに セットすることをオススメします。
JSONの形で扱うことで、サーバーサイドでの取り回しも楽になります。
また、将来的にHTTPのQUERYメソッドがRFCとして承認され実装された際には、POSTメソッド→QUERYメソッド にするだけで、サーバーサイドのロジックをほとんど修正することなく移行を完了できます。
POSTメソッド→QUERYメソッドで、リクエスト・パラメータ→リクエスト・ボディするなら、サーバーサイドの修正が若干?必要になります。
HTTP GETメソッド URL長さ制限
仕様上の制限
HTTP仕様(RFC)自体には、GETリクエストのURL長さに明確な制限はありません。制限はブラウザ・サーバー・OS側が設けています。
ブラウザ別の上限目安
| ブラウザ | URL長さ上限(目安) |
|---|---|
| Safari | 約80,000文字 |
| Chrome | 約2,097,152文字 (2MB) |
| Edge(新・Chromium版) | 約2,097,152文字 (2MB) ≒ Chromeと同等 |
| Firefox | 約65,536文字 |
| IE11 / 旧Edge(EdgeHTML版、Windows10初期) | 約2,083文字 |
サーバー側の上限 (こちらが実質的な制限になりやすい)
| サーバー | デフォルト上限 | |
|---|---|---|
| Apache | 8,190バイト | 設定で変更可能 |
| Nginx | 8,192バイト | 設定で変更可能、large_client_header_buffersで変更可 |
| IIS | 16,384バイト | |
| Node.js (http) | 16,384バイト | (v14〜) |
プロキシの制限
インターネット上のプロキシサーバーなどが長いURLを拒否する場合があり、2,000文字~約8KBが一般的です。
主要プロキシの上限
| プロキシ | デフォルト | 上限設定変更 |
|---|---|---|
| Squid | 4,096バイト | request_header_max_sizeで変更可 |
| HAProxy | 8,192バイト | tune.maxrewrite等で変更可 |
| Nginx(リバースプロキシ) | 8,192バイト | large_client_header_buffersで変更可 |
| AWS ALB | 8,192バイト(ヘッダー全体) | 変更不可 |
| AWS CloudFront | 8,192バイト | 変更不可 |
| Cloudflare | 32,768バイト(32KB) |
主な環境ごとの制限目安
| 対象 | 制限(目安) | 備考 |
|---|---|---|
| ブラウザ (Chrome/Firefox/Edge) | 数万バイト以上 | モダンブラウザは非常に長いURLを許容します。 |
| レガシーブラウザ (IE) | 2,083文字 | 互換性を考慮する場合の最も厳しい基準です。 |
| Webサーバー (Apache/Nginx等) | 8,192バイト (8KB) | 設定(LimitRequestLine等)で変更可能です。 |
| クラウド/ミドルウェア (AWS ALB等) | 8KB〜16KB程度 | ロードバランサーやWAFで制限されることがあります。 |
クエリストリングの実用的な推奨値
古いIEや古いプロキシ互換を意識するなら、2,000文字以内に収めるのが最も安全です。
SafariはURLが長くても比較的寛容ですが、サーバー側で8KB制限に引っかかるケースが多いです。
IEや旧Edge etcのレガシー・ブラウザをサポート対象外にできるのなら、8KB(2,000〜4,000文字)程度に収めるのが安全です。
まとめ
実質的な制限 = min(ブラウザ上限, サーバー上限, プロキシ上限)
一文字のバイト数
日本語
| エンコーディング | バイト数 |
|---|---|
| UTF-8 | 3バイト(ひらがな・カタカナ・漢字) |
| UTF-16 | 2バイト(基本的な文字)/4バイト(一部の漢字) |
| Shift_JIS | 2バイト |
| EUC-JP | 2〜3バイト |
現代のWeb・プログラミングでは UTF-8 が標準なので、日本語1文字 = 3バイト と覚えておくのが実用的です。
例外: 絵文字(😊など)はUTF-8で4バイトになります。
英数字
| エンコーディング | バイト数 |
|---|---|
| UTF-8 | 1バイト |
| UTF-16 | 2バイト |
| Shift_JIS | 1バイト |
| ASCII | 1バイト |
英数字(a-z, A-Z, 0-9)や記号(!, @, . など)は、UTF-8・Shift_JIS・ASCIIいずれも 1バイト です。
UTF-8
| 文字種 | バイト数 |
|---|---|
| 英数字・記号 | 1バイト |
| ひらがな・カタカナ・漢字 | 3バイト |
| 絵文字 | 4バイト |
HTTP QUERYメソッド
GETメソッドはセマンティクス(意味論)的にリクエスト・ボディを利用できません。
QUERYメソッドはリクエスト・ボディにデータを含められます。
POSTメソッド(セマンティクス(意味論)的には問題あり)で代替可能なので、策定はゆっくりと進んでいます。
2025/11、IETFにて、RFCの一段階前?、proposed standardに。
提案されてから幾星霜、RFC化が近づいています。