Perl/CGI研究室 'PERL-LABO'

Perl/CGI研究室 'PERL-LABO' TOPへ
戻る(History.Back)

GETメソッドの研究

研究内容

ブラウザからGETメソッドで送信されたデータをCGIプログラム側で受け取る仕組みを研究します。

詳細

やりとりがしたい

CGIプログラムの面白いところは、ホームページに来てくれた訪問者様と なにかやり取りというか、インタラクティブなことができるということだと思います。 アクセスカウンターやアクセス解析のような、訪問者様と特に無関係に動作する CGIプログラムもいろいろ便利ですが、やっぱり掲示板のような、訪問者様が参加できるような ものが作れるというのが楽しいです。

実際、メールフォームとかアンケートとか、なにか訪問者様から情報をもらって、 その情報を処理するCGIプログラムというのはとても沢山あります。 ここから、そういうCGIプログラムを作る基礎として、訪問者様から情報を受け取る CGIプログラムというものを 研究したいと思います。

ブラウザ側の話

情報を受け取るには、情報を送ってもらわなければいけません。 情報を送るというのは、ブラウザ側でやってくれます。 HTMLにはそのためのタグが用意されていて、 そういう、情報を送信するものをフォームと呼びます。 それでは、フォームで文字列を入力できるようにして、 そこで入力された文字列をCGIプログラムで 受け取るにはどうしたらよいか研究します。

さてブラウザからCGIに情報を送る方法として、GETメソッドというものと、 POSTメソッドというものがあります。この2つは情報の送り方が違っていて、 CGIプログラム側の受け取り方も違います。先に、GETメソッドでの情報の受信を研究しましょう。

文字列をGETメソッドで送るフォームのHTMLソースは例えば次のようになります。

<form action=get.cgi target=_blank method=get>
<input size=70 type=text name="input" value="sample text">
<input type=submit value="送信">
</form>

FORMタグでこれがフォームであることを表します。FORMタグの中で、 method=get として、GETメソッドで情報を送信するように指定しています。 INPUTタグのtype=textは文字列を入力するテキストボックスという意味。 INPUTタグのtype=submitは、このフォームで入力された情報の送信を行うボタンを表します。 nameはCGIプログラム側で入力された情報が区別できるように、情報毎に付ける名前。 valueというのはここでは一番最初に入力されている情報です。

ブラウザ上で表示するとこうです。 さて送信された情報はどうやってCGIに伝えられ、CGIではどうやってその情報を受信するのでしょうか?

結果

情報の入れ物

外部からの情報をCGIプログラムの中で受け取るには、環境変数というものを使うんだそうです。 環境変数というのは、「名前」と「値」がペアになっている、その名の通り、 環境を表す変数です。 環境というと分かりにくいですね。環境設定というべきですね。 ブラウザから送られてきたデータはまずはウェブサーバーが受け取り、 ウェブサーバーはCGIプログラムを起動しますが、 その時に、ブラウザから送られてきた情報を環境変数にセットしてくれるのです。 それで、CGIプログラムは環境変数にセットしてくれたデータを読み出すと。

もともと環境変数っていうのは、ブラウザからのデータを受け取るためにあるものじゃありません。 環境設定の情報を入れておくためにOSが用意してくれているものです。 なんでウェブサーバーがこの中にブラウザから送られてきたデータを入れるのか、 なんだか不自然に感じますが、 それがCGIのルールというものなんでしょう。ブラウザからの送られてきたデータを CGIプログラムの中で受け取るための統一ルールとして、環境変数を使うっていうのが便利だったから。 ということじゃないのかな?と想像してます。

Perlでの情報の受け取り方

受け取りたい情報が環境変数の中に入っていることが分かりました。 それではPerlで環境変数の値を知るにはどうしたらいいのかというと、 Perlでは環境変数は $ENV という変数で表される連想配列です。 $ENV{'名前'} というように知りたい情報を名前で指定して、 その情報を取り出すことができます。連想配列とかいう言葉は初めてでてきましたが、 これはCGIプログラムというよりPerlの文法の話ですね。 後で研究することにして、ここでは次の知識があればOKです。

フォームからのデータ送信形式(GETメソッドまたはPOSTメソッド)は、 $ENV{'REQUEST_METHOD'} の中に GET または POST という文字列で格納されています。

フォームから送られた情報は、GETメソッドの場合、 $ENV{'QUERY_STRING'} の中に格納されています。

この2つの環境変数をブラウザ上に表示するCGIプログラムを作りましょう。 どんな風に情報が送られてくるのか確かめてみます。

変数を画面に表示するには

変数の値を画面に表示するということは 変数の値を出力するということですが、 Perlではとても簡単です。 print文で文字列を出力するときは " で囲むんでしたが、 この中に変数が入っていると、自動的にその変数の値に変換してくれるのです。 こいつは便利。今回のCGIプログラムは簡単、「Hello world!」をちょっと変えただけでした。

作成したCGIプログラム

get.cgi
#!/usr/bin/perl

print "Content-type: text/html\n";
print "\n";

print "REQUEST_METHOD : $ENV{'REQUEST_METHOD'}<br>\n";
print "QUERY_STRING   : $ENV{'QUERY_STRING'}<br>\n";

実行結果

下の入力ボックスに文字列を入力して、送信ボタンを押してください。 別窓が開きます。いろんな文字列でテストできるように、あらかじめ 文字列を入れたフォームをいくつか用意しておきました。

考察

動きました

環境変数 REQUEST_METHOD には GET が入っていることが確認できました。 また、環境変数 QUERY_STRING に入力された文字列が入っていることが確認できました。 簡単でしたが、これはかなり嬉しいです。これで、CGIプログラムの可能性が一気に 広がるというか、いろんなことが出来るようになります。

とりあえず注意しておきたいこととしては、 環境変数 QUERY_STRING の中では、(INPUTタグのname属性で指定しておいた名前)=(文字列) と いう形でデータが入っているということですね。 ここでは、文字列を1個だけ入力するようにしましたが、このように名前付きで データが入っているので、複数の文字列を受け取る時、ちゃんと区別ができます。

文字列のコードについて

しかし、データの受信はこれで終わりじゃないんですよね。 もう1つのPOSTメソッドというのの場合は別のやり方でデータを受け取る必要があるっていうのも そうですが、それよりも大変なのは、 入力されたデータがそのままの形で送られてくるわけではないということです。 例えば、スペースが入っている場合、スペースじゃなくて + に変換されて送られてきます。 他にも、+ とか / とかは %2B、%2F みたいに %〜 という形で送られてきます。 日本語、つまり全角文字の場合も、%〜 という形で送られてきます。 これは、ブラウザから送れる文字に制限があるからですね。 送れない文字というものもあって、それを送るためにこんな変換をしているんです。 CGIプログラム側で、これを元の文字に戻すっていうことをしなきゃいけません。 さらにこの時、文字コードっていうものが絡んできます。 なかなか大変ですが、後でじっくり研究しましょう。

GETメソッドの特徴

データの送り方にGETメソッドとPOSTメソッドがありますが、GETメソッドでのデータ送信の 特徴は、データがURLの後ろに付加されて送られる、という点です。 上の実行結果の送信ボタンを押すと新しいウィンドウが開きますが、アドレス欄に URLが表示されていますね。そこを見ると、面白いことに、 環境変数 QUERY_STRING に入っている文字列と同じものが URLの後ろにくっついているのです。POSTメソッドの場合、こうはなりません。

環境変数 QUERY_STRING というのは、 ブラウザから送られたデータが入っているというよりも、 URLの後ろの ? から後ろの部分が入っているんですね。 これ、実は結構いろんなことに応用できそうじゃありませんか? CGIにデータを送るにはフォームを使いますが、フォームを使わなくても、 固定のデータなら直接CGIプログラムにデータを送ることができます。 例えば、次のリンクをクリックしてみてください。

get.cgi?ABCDE
get.cgi?SAMPLE TEXT
get.cgi?日本語

このように、フォームを使わずにリンクを使ってCGIプログラムにデータを送ることが できます。何に使えるのか?例えば「はい」「いいえ」という2択の質問なら、 フォームを使わなくてもリンクでもいいとか。 この例えだとあんまり面白くありませんが、 なんかいろいろ使えそうだと思いませんか?

まぁ使い道はともかく、URLの後ろにデータを付け足すっていうのは とても特徴があるものですので、覚えておきましょう。

分かったこと

  1. 送信方法は $ENV{'REQUEST_METHOD'} に入っています。
  2. GETメソッドの場合、データは $ENV{'QUERY_STRING'} に入っています。
  3. Perlで環境変数の値を得るには、連想配列 $ENV を使用します。
  4. 送信データは、(INPUTタグのname)=(内容) という形式です。
  5. 空白は + に変換されて送信されていました。
  6. 送信データに ?、&、全角文字などが含まれていると、%ナニナニ と変換されていました。
  7. 文字列は変換されて送信されるため、そのままでは日本語などを正しく処理できません。
  8. GETメソッドの場合、URLの ? の後ろに送信データが追加されています。
  9. URLに送信データが含まれるので、通常のリンクでCGIプログラムにデータを送ることができます。

メモ

  1. 複数のデータを受けると、& で区切られてきます。
  2. 送信できるデータの長さには制限があり、255バイトまでらしいです。
Perl/CGI研究室 'PERL-LABO' TOPへ
戻る(History.Back)

Copyright (c) 'PERL-LABO' All Rights Reserved.  リンクフリーです。