POST でパラメータを受け取る

QUERY_STRING でパラメータを受け取る」で勉強した、URL の最後に「?」をつけ、その後にパラメータ(QUERY_STRING)を記述する、という方法は HTTP リクエストのメソッドが「GET」の時に使われるものでした。
ですが、ブラウザやサーバーソフトウェアには URL の長さに制限がある場合が多く、あまり長いパラメータは送る事ができません。「GET」メソッドはあくまでも「コンテンツの取得」が主な目的であるべきで、あまり多くのパラメータを送信すべきではないのです。
「データの送信」が主な目的な時には「POST」メソッドを使います。例えば「掲示板への書き込み」は、投稿者の名前やメールアドレス、本文などの「データの送信」が目的ですので、「POST」メソッドですね。(^_^)
「POST」メソッドではパラメータの長さに制限がなく、サイズの大きいデータでも受け取る事ができます。というわけで、今回は「POST」メソッドが使われた時のパラメータの受け取り方を勉強したいと思います。


といっても、その方法は「GET」とほとんど変わりません。ただ、読み込む先が違うのです。「POST」の場合、渡されたパラメータは「標準入力」に入っています。QUERY_STRING と同じく、「名前=値」の形式が使われ、複数の値がある場合は「&」でつながっています。
標準入力の内容は特殊ファイルハンドル「STDIN」から読み込む事ができます。

my $query;
if ($ENV{'REQUEST_METHOD'} eq "POST") {
  $query = join "", <STDIN>;
} else {
  $query = $ENV{'QUERY_STRING'};
}

REQUEST_METHOD には、リクエストに使われたメソッドが入っているので、"POST" ならば STDIN の内容を行入力演算子と join を組み合わせて全て読み込み、"GET" ならば QUERY_STRING の内容を読み込みます。これで GET と POST 両方に対応できますね。
あとは、QUERY_STRING の時と同じように

my %param = map { /([^=]+)=(.+)/ } split /&/, $query;

とすればハッシュ変数 %param に名前と値の組が収まりますね。(^_^)


「POST」メソッドを使ったフォームは、以下のようになります。

<form action="post.cgi" method="POST">
  <p>
    <label for="name">名前:</label>
    <input type="text" name="name" id="name" />
  </p>
  <p>
    <label for="body">本文:</label>
    <textarea name="body" id="body" cols="20" rows="3"></textarea>
  </p>
  <input type="submit" value="送信" />
</form>

この場合、以下のように表示されます。









複数行のテキストボックス(<textarea>)を入れてみました。上のフォームの動作を確かめる為に、CGI にしてみました。(実は上で例示したフォームも動作します)
echo.cgi 実行結果ソースコードテンプレート
送られてきたパラメータをそのまま表示します。
GET の時とあまり違いがないので、簡単ですね。(^_^)