NDW

アプリ開発やトラブルシューティング等のノウハウ、キャンプや登山の紹介や体験談など。

1. システムエンジニアリング 設計技術

WebアプリでのHTTP GETとPOSTの比較

投稿日:

はじめに

GETとPOSTの比較

GETメソッドはページを取得するため、POSTはデータをサーバに送信するために使用されます。
両者の違いは次の通りです。

観点 GET POST
データ定義場所 URIに付加(クエリ文字列)
(ボディ部へのデータ指定はサポート外 ※1)
主にボディに付加
(URIにも付加可)
データ可視性 データはURIに付加されるので誰でも確認可 データはURIに付加されないので簡単には確認不可
戻る・再読み込み 問題なし データが再送信される。※2
フォームを再送信するかを確認するダイアログが表示される。
ブックマーク保存 保存可能 保存不可 ※3
キャッシュ化 キャッシュされる キャッシュされない
エンコーディング なし application/x-www-form-urlencoded
(バイナリ送信のマルチパート使用時はmultipart/form-data)
ブラウザ履歴 履歴上に残る。
(履歴の保存対象となるURIにデータがあるため。)
データは履歴に保存されない。
データ長の制限 データを付加したURIは約2000文字以下が安全 ※4 制限なし ※5
データ種類の制限 ASCII文字のみ許可 制限はなく、バイナリデータの使用も可
安全性 POSTより低い
パラメータがURI上に付加される、ブラウザ履歴やサーバ側のアクセスログに残るため。
パスワード等の機微なデータは扱えない。
GETより安全
パラメータはURIに付加されないため、ブラウザ履歴やアクセスログに残らない。
  • ※1: GETはURIで指定されたリソースを受け取ることに主眼が置かれており、ボディにデータを指定する方法は想定していません。
    • HTTP1.0を規定するRFC1945, HTTP1.1を規定するRFC2068, RFC2616では、GETでのボディ指定は明記されていません。
    • 改訂版のRFC7231(Section 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.
    • 互換性を考えるとGET時のボディ設定は回避した方が安全です。
    • 詳細はこちらを参考のこと。
  • ※2: POSTで表示されたページURIをブックマークすると同URIをGETするブックマークが保存されるます。そのため、保存されたブックマークを開いた際の挙動は実装に依存します。
  • ※3: 戻る・進む・再読み込みで更新データが重複登録されるのを回避するために画面遷移方式としてPRGパターン(Post/Redirect/Get)が使用されます。
  • ※4: ブラウザやサーバで扱えるURIの上限は次の通りです。
    • HTTP1.1を規定するRFC2616(Section 3.2.1)等では上限を決めておらず、改訂版のRFC7230では8000オクテットが推奨されましたが、現在ではブラウザ・サーバ依存の状況になっています。例えばChromeでは2MB、Apache HTTPサーバでは8KBだったりします。
    • 過去のブラウザやサーバとの互換性を考えるなら上限2000文字が安全のようです。特定のブラウザ・サーバ環境を使用するのであれば、その環境で許容される最大長を使用できます。
    • なお、この上限を超える場合はサーバ側で応答コード414(URI Too Long)を返却します。
    • 詳細はこちらを参考のこと。
  • ※5: HTTPの仕様として上限はありませんが、一般的なWebサーバではDoS攻撃を回避するために既定でPOSTデータの上限サイズを設けています。例えばWildflyの既定の上限サイズは10MBになっています。

業務実装での考察

  • 検索画面における検索実行はGETでやるかPOSTでやるか?
    • 経験的に以前は「画面初期表示はGET、検索実行はPOST」としていたが、画面表示も検索もデータの検索・取得系の処理要求なのでGETの方がメソッドの目的に合致する。
    • 検索条件を指定して検索画面を開くようなケースではGETの方が容易に実現できる。
      (URIに検索条件をクエリ文字列として付与するだけで実現可。POSTの場合はフォームデータの作成等の処理が必要となりGETより手間がかかる。)
      • メールに記載された処理結果確認用URIを開き、処理結果を直接開くような場合
      • 登録完了後に検索画面で登録結果を初期表示するような場合
      • 一覧画面で対象を選択して編集後、同じ条件で一覧画面を表示する場合(編集後に同一の検索条件を復元)
    • 金融や物流等の検索画面では検索条件が10~20項目以上ある場合もある。このようなケースではクエリ文字列が非常に長くなるのでPOSTの方が適しているかもしれない。
    • 検索条件として画像等のバイナリを扱う場合、GETでは実現できないので、POSTを使用する必要がある。
    • 検索画面に関して、基本はGETを使用するが検索条件項目が多い(例えば10個以上)場合はPOSTを使用、等の設計ルール(標準化)が良いかもしれない。
    • RESTfulの場合、POSTオーバーロード(POSTに複数の役割・機能も持たせる)という方式で複雑な検索条件を実現することもできる。







-1. システムエンジニアリング, 設計技術

関連記事

VULTR: SSH鍵の作成とVPSの構築

VULTRでVPSを作成し、Tera Term(SSH)で管理する方法について説明します。 概要 VULTRにおいて、次の前提でVPSを構築する手順を説明します。 “New York(NJ …

セッションタイムアウトの必要性

「セッションタイムアウトって何で必要なんですかね?」という問いがあった。 その人は「セッションデータの肥大化によるリソース枯渇や性能劣化を防止」という意見。 自分の場合、「それもあるかもしれないが、ど …

wildflyへのwarデプロイの自動化

更新したWebアプリをWildflyにデプロイするのが面倒なのでスクリプトを作成してみました。 前提 実行環境はCentOS Linux 7です。 JavaEEのWebアプリの配布形式であるwarファ …

保守運用

運用 と 保守 の 違い

若い頃は 運用 と 保守 の違いを調べても良くわからなかった… この辺を使い分けられる人をほとんど見たことない… ある事項が運用なのか保守なのかの話をすると認識が合わない&#8 …

JavaでのZIP暗号化の考察

法務系業務を行うシステムを設計するにあたり、次のような要件がありました。 CSVファイルの暗号化方式として、当初からパスワード付きZIPファイルの使用を検討していたため、ZIP圧縮を使用する前提で調査 …