【Webプログラミング - Code.003】CGI(Perl)基本動作 その3:「GETとPOST」

   Code.003                                                 2002年10月21日発行
■━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━■
                           【 Webプログラミング 】

                       〜 猫的プログラマーとその軌跡 〜
■━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━■

              ▼毎週月曜日に配信しています。
              ▼等幅フォントでご覧いただくとキレイに見えます。
              ▼登録・解除はこちらから可能です。
                < http://www.ichikoro.com/webp/ >
                  ※ぜひお友達にもご紹介ください(^^)/

2ちゃんねるのメルマガでも紹介されていた、Web上で出来ると評判の
「逆転裁判」の体験版をやってみました。

    ・逆転裁判2
      http://www.capcom.co.jp/saiban2/
        ※FLASHってすごい(笑)

ゲーム的に見ても面白いですね!
「意義アリ!」などの演出、それを受けた証人のリアクションが何とも
気持ちいいのです。法廷という一見すると地味な世界をここまでエンター
テイメントにしてみせる、その力量に感服です。

給料入ったらゲームボーイアドバンス買っちゃおうかなぁ。
と、ここで改めて思ったのは、ソフトがハードを牽引するということです。
これはインターネットの世界でも一緒ではないでしょうか?

さて、ここで問題です。
ブロードバンドのキラーコンテンツって何でしょう?
重い物もスイスイ落とせるから動画?
いつも接続していられるからインスタントメッセンジャー?

....ホントに、それがキラーコンテンツですか?
と疑問に思うかつべなのでした(今日のわんこ風)

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 CGI(Perl)基本動作 その3:「GETとPOST」
──────────────────────────────────────
CGIへ値を渡す方法は2種類あります。
前回ご紹介したように、

  (1)URLの最後に、クエリーを付加する
    http://www.ichikoro.com/hoge.cgi?name=value

  (2)FORMタグで渡す
    <FORM action="hoge.cgi">
      <INPUT type="hidden" name="name" value="value">
    </FORM>

なのですが、FORMタグで渡す方法にも2種類あるのです。
それが、GETとPOSTなのです。

───────
 ソース1(HTML)
───────
<HTML>
<HEAD>
  <TITLE>リクエストメソッド判定</TITLE>
  <STYLE type="text/css"><!--
    DT {font-weight:bold}
  -->
  </STYLE>
</HEAD>
<BODY bgcolor="#FFFFFF">

<H2 align="center">リクエストメソッド判定</H2>

<DL>
  <DT>■リンクから実行(GET)</DT>
  <DD><A href="method.cgi?q=Hello">リンクから実行</A><BR><BR></DD>

  <DT>■FORMタグから実行(GET)</DT>
  <DD>
    <FORM action="method.cgi" method="GET">
      <INPUT type="text" name="q" value="Hello">
      <INPUT type="submit" value="FORMタグから実行(GET)">
    </FORM>
    <BR>
  </DD>

  <DT>■FORMタグから実行(POST)</DT>
  <DD>
    <FORM action="method.cgi" method="POST">
      <INPUT type="text" name="q" value="Hello">
      <INPUT type="submit" value="FORMタグから実行(POST)">
    </FORM>
    <BR>
  </DD>
</DL>


</BODY>
</HTML>



───────
 ソース2(CGI)
───────
#!/usr/bin/perl

;#
;#リクエストメソッドを判定する(method.cgi)
;#

use strict;


#==================================================#
#                  メインルーチン                  #
#==================================================#
package main;
{
  my $q;        #クエリーを入れる
  my $method;   #メソッドを入れる

  #--------------------------------------------------#
  #               GETかPOSTかを得る                  #
  #--------------------------------------------------#
  $method = $ENV{'REQUEST_METHOD'};

  #--------------------------------------------------#
  #            GETの場合は環境変数から得る           #
  #--------------------------------------------------#
  if( $method eq "GET" ){
    $q = $ENV{'QUERY_STRING'};
  }
  #--------------------------------------------------#
  #           POSTの場合は標準入力から得る           #
  #--------------------------------------------------#
  elsif( $method eq "POST" ){
    my $length = $ENV{'CONTENT_LENGTH'};  #データ長を得る

    #-- 標準入力(STDIN)から$lengthバイト分$qへ入れる --#
    read(STDIN, $q, $length);
  }


  #--------------------------------------------------#
  #                 ブラウザに出力                   #
  #--------------------------------------------------#
  print "Content-type: text/html\n\n";
  print <<"END_OF_HTML";
<HTML>
<HEAD>
  <TITLE>REQUEST METHOD判定</TITLE>
</HEAD>
<BODY bgcolor="#FFFFFF">

<H2 align="center">REQUEST METHOD判定</H2>

<DIV align="center">
<TABLE border="1">
  <TR>
    <TD>METHOD</TD>
    <TD>$method</TD>
  </TR>
  <TR>
    <TD>q</TD>
    <TD>$q</TD>
  </TR>
</TABLE>
</DIV>

</BODY>
</HTML>
END_OF_HTML


  #--------------------------------------------------#
  #                    正常終了                      #
  #--------------------------------------------------#
  exit(0);
}


───────
   実行方法
───────
テキストエディタ(メモ帳やSimpleText)などで上記のソース(プログラム)を
保存してください。ソース1は適当な名前(xxxx.html)でOKです。ソース2は
「method.cgi」とすると、HTMLを変更せずにすみます。

CGIの詳しい実行方法については、Code.001をご参照ください。
http://backno.mag2.com/reader/BackBody?id=200210050820000000080329000

直接URLを叩いたりブックマーク(お気に入り)から、又はフレームの一部とし
て実行したりと色々試してみてください。

  ★重要!
  このCGIはセキュリティーホールを含みます。
  学習以外の用途には使用しないでください。


───────
    解 説
───────

■GETとPOST
  Webサーバに対して「ファイルをください」と問い掛ける際、その方法は
  2通りあります。冒頭でも書いたとおり、GETとPOSTです。

    ・GET
      通常、クライアント(ブラウザのこと)から指定したファイルを
      くれるよう、サーバに問い掛ける際に使用します。

        ・Aタグなどで、普通にURLを訪れる場合はGETになります。
          ※URLの最後にクエリーを付加した場合も
          GETになります。

        ・FORMタグでmethod属性を何も指定しないか、method="GET"
        とするとGETになります。
          ※submitすると、URLの最後にクエリーを付加した状態
          でサーバにアクセスされます。つまりリンクと変わら
          ないのです。

    ・POST
      GETは渡せるデータ量に限界があります。
      どれくらい渡せるかは、サーバやクライアントに依存するため
      一概に言えませんが、あまり巨大なデータを渡すことはできま
      せん。許容量を超えると途中でデータが切れるてしまいます。

      そこで登場するのがPOSTです。
      POSTの場合はGETと違い、大量のデータでも途切れることなく
      全て送受信することが出来ます。
        ※もちろん、重たいデータだと転送時間がかかったり、
        サーバに負荷がかかります。


  「じゃぁ、POSTはどうやって送っているのだ?」という、最もな疑問は
  説明するとメンドイので興味のある方は下記のサイトで勉強してください。

    ・ネットワークプログラミングの基礎知識
      http://x68000.startshop.co.jp/~68user/net/


■プログラム的な違いは?
  さて、プログラムの説明に移りましょう。
  今回のポイントは

    (1)GETとPOSTの違いを「環境変数」で見極める
    (2)GETとPOSTでデータの取って来る所が違う

  この2つです。

    (1)GETとPOSTの違いを「環境変数」で見極める
       これはもう単純に

        REQUEST_METHOD

      という環境変数の中に“GET”か“POST”という文字列
      が入っています。上記のプログラムで言えば下記の部分
      で取得しています。

>        $method = $ENV{'REQUEST_METHOD'};


    (2)GETとPOSTでデータの取って来る所が違う
      GETの場合は

>        $q = $ENV{'QUERY_STRING'};

      といった具合に、環境変数「QUERY_STRING」から取得できます。
      そのまま変数に入れてやればOKです。

      POSTの場合はGETよりも若干複雑です。

>        #-- 標準入力(STDIN)から$lengthバイト分$qへ入れる --#
>        read(STDIN, $q, $length);

      このように標準入力(STDIN)から情報はやってきており、
      read関数で得るケースをよくみかけます。read関数で必要な
      データ長は、環境変数「CONTENT_LENGTH」から得ることが可
      能です。


───────
   次回予告
───────
次回はこれら渡した値を受け取り、利用する方法を紹介します。

ただ、一つだけ問題があります。
実はURLでは使ってはいけない文字があるんです。
例えば全角文字をそのままURL上に記述してはいけません。

  http://www.google.co.jp/search?q=愛のタテーガミ〜♪   ← マズイ
                   ~~~~~~~~~~~~~~~~
しかし、どうしてもそれを使用したい場合もあります。
そんな時は対象の文字に対して「URLエンコード」を施してやります。

例えばGoogleで検索した場合、

  http://www.google.co.jp/search?q=%88%A4%82%CC%83%5E%83e%83K%83%7E%81%60%81%F4

というようなURLを見たことありませんか?

URLエンコードは通常ブラウザ(クライアント)が行います。
ところが、CGIで受け取った値もURLエンコードが施された状態のため、
そのままでは利用できません。

というわけでURLエンコードされた文字列を元に戻し、それを表示するま
でをご紹介します。やれやれ、色々とメンドくさいですね(^^;)

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
                           編    集    後    記
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
「4年の歳月と33万1000人のボランティア」
この世界的規模のプロジェクトが先日ゴールを迎えたというニュースが
流れてきました。

 ・64ビット暗号、分散コンピューティングでついに解読
  http://www.hotwired.co.jp/news/news/technology/story/20021008301.html

現在、Web上で使用されているのは128ビット暗号です。
これを解析するのは、今のところ難しいと言われていますが、
時間の問題なのかもしれません。

もともとこの技術は、解読するための「鍵」のパターンがほぼ無数にあり、
全てを試すには時間がかかり過ぎる(それこそ数十年〜数百年)ことから、
現実的に解けないと言う技術なのです。本質的には他者に解読できる暗号
である、ということなのです。

技術が進むにつれ、こうした問題は出てきます。
しかし、一番の問題はそれを使う人間次第ともいえます。
例えば、同じようなプロジェクトでSETI@HOMEと呼ばれる物があります。
宇宙から地球にやってくる電波を解析し、そこに宇宙人のメッセージが
ないか探すプロジェクトです。

近い将来、解析スピードが上がれば、あなたのパソコンに彼らから
“Hello! Friend”何てメッセージが出てくるかもしれませんよ!

    ・SETI@HOME(日本語版)
      http://www.planetary.or.jp/setiathome/home_japanese.html

それでは、また来週お会いしましょう! (^-^)/~~

■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■

                   【 Webプログラミング Code Sample 】

                    発  行 : ichikoro.com
                発行責任者 : 勝部 麻季人
                              < katsube@ichikoro.com >
                 Webサイト : < http://www.ichikoro.com/webp/ >
            お問い合わせ先 : < mm-webp@ichikoro.com >

                            Powerd by まぐまぐ
    All Right Reserved, CopyRight(C) 2001 Webプログラミング Code Sample
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■