Perl初心者の部屋  序章  1章  2章  3章  4章  5章  6章  8章  9章  10章
PageID:New Perl-FAQ7J
Last updated:97.03.22

Perl for Win32 Frequently Asked Questions (FAQ)

7章の翻訳者:目黒のさかな(山川)さん<sakana@ask.or.jp>

7. Web プログラミング (CGI と PerlIS)

7.1. HTTPとは何ですか。 それに関する情報をさらに得るにはどうすればいいのでしょうか?

 HTTP (HyperText Transfer Protocol)はブラウザが Webサーバと会話するのに使うプロトコルです。HTTPスタンダードの公的な仕様は、W3 Consortium web server で得られます:

http://www.w3.org/pub/WWW/Protocols/

 いくつかの入門ページを Yahoo HTTP page で見つけることができます:

http://www.yahoo.com/Computers_and_Internet/Internet/World_Wide_Web/HTTP/

7.2. CGIとは何ですか。 それに関する情報をさらに得るにはどうすればいいのでしょうか?

 CGI (Common Gateway Interface) は、サーバプログラムを走らせるために Web server に使われるプロトコル(規約)です。CGIをサポートしているスクリプトは、"CGIスクリプト"と呼ばれることがありますが、これが CGIは言語だという誤った印象を与えています。

 CGIに関する古典的情報は、NCSA server で得られます:

 http://hoohoo.ncsa.uiuc.edu/cgi/

 これを読んでないのでしたら、今すぐ読んで下さい。それでもまだピンと来ないようでしたら、この Yahoo CGI page をチェックなさい:

 http://www.yahoo.com/Computers_and_Internet/Internet/World_Wide_Web/

    CGI___Common_Gateway_Interface/

(URLは一つです、ライン入力は忘れて下さい).

 Perlでの CGIプログラミングのための次の URL もチェックなさい:

 http://www.perl.com/perl/faq/perl-cgi-faq.html

 まだ分からなかったら、CGIスクリプトの書き方を詳しく書いた本をどれか一冊買いなさい。

7.3. CGIスクリプトからグラフィックファイルをを出力するには どうすればいいのでしょうか?

 UNIX と Win32プラットホームの大きな違いの一つは、テキストまたはASCIファイルとバイナリファイルの間にある違いにあります。グラフィックファイルを返すために、あなたはそれがバイナリファイルだと特別に指定してやらなければなりません。そうすれば、標準出力はバイナリデータを受け入れるのです。こんなことをやって見て下さい:

    $MY_FILE_NAME = 'Penelope.jpg';
    $CHUNK_SIZE = 4096;

    open( MY_FILE, "<$MY_FILE_NAME" )
      or die( "Can't open $MY_FILE_NAME: $!\n" );

    print "Content-type: image/jpeg\r\n";
    print "\r\n";

    binmode( MY_FILE ); # These are crucial!
    binmode( STDOUT );

    while ( $cb = read( MY_FILE, $data, $CHUNK_SIZE ) )
    {
      print $data;
    }
    
    close( MY_FILE );

 PerlISスクリプトだと、さらに余分にヘッダ情報を加えなければなりません。下記のように。

7.4. PerlISのもとでは私のCGIスクリプトはちゃんと走っていないように思われます。 何がおかしいのでしょうか?

 PerlIS の下で走るスクリプトは CGI/1.1 specification (see question 7.2) に定義されている"nph"スクリプトにとてもよく似ています。すべてのHTTPレスポンスステータスラインを指定しなければなりません。同じく、すべてのヘッダも。

  PerlIS の下で動くサンプルです:

    print <<"END";
    HTTP/1.0 200 OK
    Content-Type: text/html

    <HTML>
    <HEAD>
      <TITLE>PerlIS Response</TITLE>
    </HEAD>
    <BODY>
      This is a PerlIS response.
    </BODY>
    </HTML>
    END

 上の例のように HTTP status line を加えないなら、ブラウザは HTTP/0.9 server と会話していると取ってしまいます。そしてあなたのレスポンスヘッダをあなたが返そうとしている HTML の一部として扱おうとします。 (HTTP のスペック(規格・仕様書)によると、1.0 と 0.9 サーバの違いは、ステータスラインの存在であり、ブラウザは 0.9のレスポンスを受け入れるべきだとされる)。だから、あなたのヘッダはブラウザのウィンドウに現れてしまうのです、あなたは望まないでしょうけど。

 HTTPステータスラインがないと、PerlIS は Content-Type headerを付け加えるというのは誤った認識です。これは誤りであり、小さな sockets codingでチェックできます。

  複雑な PerlISプログラムをするのなら、HTTP仕様書(see question 7.1)をたぶんもう一度よく読むべきでしょう。

  Philip Nelson が PerlIS と CGI の違いについて良い解説を書いています。
 (http://www.dct.com/~nelsonp/IISHeader.html)

[Any other suggestions?]

7.5. 私のスクリプトがPerl for Win32のもとで走っているのか、 あるいは PerlISのもとで走っているのかどうすればわかりますか?

 PerlIS は、PerlISの下で実行されるスクリプト用に環境変数 PERLXS をセットします。次のスクリプトは、perl.exe CGIスクリプト、 PerlISスクリプト、どちらとしてでも走ります。これは、その環境変数をチェックしステータスラインを出力する必要があるかどうか判断します。

    print "HTTP/1.0 200 OK\r\n" if $ENV{PERLXS} eq "PerlIS";
    print <<"END";
    Content-Type: text/html

    <HTML>
    <HEAD>
      <TITLE>Both</TITLE>
    </HEAD>
    <BODY>
      This script will work with perl.exe and PerlIS.
    </BODY>
    </HTML>
    END

7.6. Perl for Win32ではどんなCGIモジュールが走るのですか?

 CGI.pm が Perl for Win32 で動作します。ここで入手できます。

http://www-genome.wi.mit.edu/ftp/pub/software/WWW/cgi_docs.html

 次に注意。CGI.pm がWindowsNT や Windows95 と動く前に、CGI.pm の $OS 変数を変更する必要があります。

[Any other CGI modules work with Perl for Win32? -ESP]

7.7. 私のスクリプトでリダイレクションを使うにはどうしたらいいのでしょうか?

 普通ユーザーに見えないやり方でクライアントのブラウザを別のファイルやスクリプトに振り向けるのに、リダイレクションを使うことが出来ます。 それには Locationヘッダが必要で、またあなたが PerlIS を使っているのだったら、同じく特別のHTTPコードが必要です。次のコードはブラウザをあるテキストファイルへ振り向けます。

    print "HTTP/1.0 303 See Other\r\n" if $ENV{PERLXS} eq "PerlIS";
    print <<"END";
    Content-Type: text/plain
    Location: /text/mytextfile.txt
    END

 注意。もし CGI(perl.exe)が使われているなら、サーバがそのロケーションを探し出して持ってきてブラウザに送りますので、ブラウザはその内容はあなたのスクリプトの URLからのものだと考えます。PerlIS が使われているなら、ブラウザは自分でそれを持って来なくてはならず、リダイレクトされた先のリソースの URLはユーザに表示されるということになります。

 あなたが PerlIS を使っているのだったら、HTTP status codes 301 (Moved Permanently), 302 (Moved Temporarily), 303 (See Other)をチェックして、そのどれがあなたのアプリケーションにもっとも適切か理解すべきです。
See
question 7.1.

7.8. cookiesとは何で、どのように使えばいいのでしょうか?

 クッキーとは、サーバがクライアントに将来のアイデンティファイ(身元確認)のために与えることの出来るデータのパケット(packets) です。NetScapeによって最初に定義されたもので、ここにそのクッキーの定義があります:
  
http://home.netscape.com/newsref/std/cookie_spec.html

 あなたのファイルの CGI(for PerlIS, HTTP response)ヘッダのひとつとして、クッキーをセットすることが出来ます。クッキーが環境変数 HTTP_COOKIE を通して送られるなら、あなたはクッキーを受け取ることが出来ます。ここに簡単なスクリプトを紹介します。ユーザーが何回ページにアクセスしたかを数えるものです:

    $cookie = $ENV{HTTP_COOKIE};
    
    $count = ( $cookie ) ? (split( "=", $cookie ))[1] : 0;

    $count++; # counting this visit.

    if ( $count > 1 )
    {
      $welcome = "Welcome back for visit #$count to this page!";
    }
    else
    {
      $welcome = "Welcome to my page for the first time!";
    }

    $cookie = "COUNT=$count";

    print "HTTP/1.0 200 OK\r\n" if $ENV{PERLXS} eq "PerlIS";

    print <<"END";
    Content-Type: text/html
    Set-Cookie: $cookie

    <HTML>
    <HEAD>
      <TITLE>Cookie Sample</TITLE>
    </HEAD>
    <BODY>
      $welcome
    </BODY>
    </HTML>
    END

 消えてしまわないクッキーをセットするには、ドメインを定義し、期限(expiration dates)その他 etc を指定します。上記の仕様書を参照のこと。

7.9. 利用者のE メールアドレスを得るにはどうしたらいいのでしょうか?

 尋ねないでEメールアドレスを得ることは、一般に不可能です。Eメールアドレスが必要なら、フォームでアドレスの記入欄を提供しなさい。

 HTTP仕様書(question 6.2参照)はHTTPリクエストヘッダを、"From"として定義しており、接続してきたユーザーのEメールアドレスをそれに含めることは可能です。環境変数 HTTP_FROMを使えば、あなたのスクリプトはEメールアドレスを探し出すことは可能ですが、それはほとんど供給されていませんので、実際は当てにはできません。

 リクエストがどこから来たかをこっそり特定するやり方はいろいろあります。接続に使われる IP addressをチェックするとか。けれどこの方法では e-mailアドレスを知ることはできません。

 一般に、本人に認識させずに e-mail address を取得するのは、プライバシーの侵害だと考えられています。たぶんそれが、困難にされている理由でしょう。

7.10. X を行うCGI スクリプトが必要なのです。 以前にそれをやった人は誰かいないでしょうか?

 Web上にはいくつかの CGIスクリプトアーカイブがあります。あなたが望んでいるものそのものを見つけられないかもしれませんが、何かしら適用できるものを見つけられるでしょう。

 もっとも有名なスクリプトページは次の二つです:

[他には?  -特記]

 注意すべきは、ほとんどのスクリプトアーカイブは UNIX向けスクリプトだということです。だから、それを走らせるにはあなたは何らかの修正(adaptations)をしなければならないかもしれません。(see question 5.7)

 これは Perl-Win32-Users list でもっとも多い質問の一つです。時々それはこんなふうに表現されます:「プログラムを書かなければなりません。これがその仕様書です。どうぞ金曜日までに e-mailで送って下さい」。のぞむらくは、この文書の読者が次の理由を理解できますように。これらのメッセージがたいてい非難という答えをもらうか無視されるその理由(わけ)を。

7.11. 引数を取るCGI プログラムを、Web サーバで実行せずにテストするには どうすればいいのでしょうか?

 コマンドラインから CGIプログラムをテストする堅いやり方は、環境変数と標準入力を Webサーバがやるようにセットすることです。(これについてもっと詳しくは CGI 1.1 規格仕様書を参照 -- question 7.2)

 簡単なのは CGI.pmを使うことです。 CGI.pm とは Perlプログラミング用の Perlモジュールです。これはコマンドラインから変数(arguments)を使って CGIプログラムを走らせる簡単な仕組みを提供してくれます。

7.12. 私のCGI スクリプトから出力した"Content-Type"ヘッダがWeb プラウザに 現れました。何が原因なのでしょうか?

 あなたは IIS Web上で PerlISを Perlインタプリタとして使っていながら、(これはinstall.batでデフォルトでセットされます)、HTTPステータスラインを出力していません。プログラム修正について詳しくは次を参照。 question 7.4

7.13. 私のブラウザからCGI スクリプトを走らせようとした時、代わりに "application/x-perl"タイプのファイルをダウンロードしようとします。 何が原因なのでしょうか?

 Webサーバのコンフィギュレーションに誤りがあります。WebサーバはPerlプログラムが実行すべきものだと知りません。だからそれをブラウザにそのまま返そうとするのです。Perlスクリプトは実行されるべきものだとWebサーバに教えるコンフィギュレーションの方法についての詳細は、このドキュメントの section 6 を参照して下さい。


ご意見、ご要望は、 電子メールまたは 投稿にお願い致します。

ホームページへ戻る。 | ページtopへ