『INTERNET ホームページ快適作成テクニック』

Part.2 CGIとSSIを利用する

Chapter.2

 Chapter.1で述べたように、CGIやSSIを利用するためには、それなりの知識が要求される。UNIXの知識も必要だ。Perlが使えればもっといい。開発環境があればベストだ。そして、これらの知識が、当然要求されることになる。  そう、昨日今日パソコンをはじめたりインターネットにつなげたり、といったユーザーでは、まずCGIやSSIを利用したホームページなんて望むべくもないのである。  しかし、そう言ってしまっては身も蓋もない。そこで本書では、そんな初心者ユーザーでも、とりあえず本書を読みすすめ、サンプルを打ち込んでみれば、なんとかCGIやSSIを利用したホームページが作成できるよう、実例をあげながらCGIとSSIの解説をしていくことにする。  最初から無理をすることはない。サンプルを打ち込み、実際に表示させてみて、気に入らない部分を改造してくれればいい。そうやって真似ていくことで、自力でCGIやSSIを利用することができるようになるだろう。  また、CGIやSSIを利用すれば、実に多くのことができるが、現実的にはホームページにアクセスカウンタをつけたり、あるいは現在時刻を表示させたり、また掲示板機能をつけたりしたい、といった要望が多いようだ。それらの要望にできるだけ応えられるようなサンプルを掲載したから、自分なりに改造してどんどん利用していただきたい。  では、CGIやSSIを利用した素敵なホームページを夢見て、ちょっと難しいけどスタートしよう。


◆CGIを使う

特別なヘッダ

 まず、次のことを覚えておいてほしい。

  CGIプログラム(CGIスクリプトとも呼ばれる)は、最初の出力行に次に示す3つのヘッダのいずれかと、それに続く空行から始まる。

・Content-type:
・Location:
・Status:

 とくに、空行は始まりのヘッダとCGIプログラムが返すデータとの境界として使われるため、忘れないように注意。
 もう少し具体的に解説しておこう。

・Content-type:
 Content-typeヘッダは、CGIプログラムが送出するデータの型を示すのに使われる。次に示すように、Content-typeヘッダは、MIME形式で定義される。
   HTMLファイル      Content-type:text/html
   テキスト          Content-type:text/plain
 Content-typeで定義されているMIME形式とは、Multipurpose Internet Mail Extentionの略で、テキスト以外の画像や、バイナリファイルをインターネットのメールに添付するのに使われる。
 MIMEエンコーディングする場合は、インターネットメールの場合も、「Content-type:」で続くファイルの形式を示すことになっている。
 よく使われるContent-type:には、次のようなものがある。
  ファイル形式 Content-type
  テキスト   text/plain
  HTML     text/html
  GIF画像    image/gif
  JPEG画像   image/jpeg
  PostScript  application/postscript
  MPEG動画   video/mpeg
・Location:
 Locationヘッダは、WWWサーバの別の文書を開くのに使われる。
 文書はURLで指定するため、同じサーバの文書でも他のサーバの文書でも、同様に記述できる。いくつか例を示すと、次のようになる。
   Location: /~nohoho/omake.html
   Location: http://foo.bar.co.jp/
   Location: http://hana.mogera.co.jp/index.html
 上記のLocationヘッダの記述は、HTMLのタグで、次のように記述するのと動作上は変わらない。
   <A HREF="/~nohoho/omake.html">おまけ</A>
   <A HREF="http://foo.bar.co.jp/">ふうばあ会社</A>
   <A HREF="http://hana.mogera.co.jp/index.html">花もげら株式会社</A>
 しかし、CGIプログラムの場合、ソースを見てもどこにリンクが張られているのかわからないという違いがある。HTMLなら、どこにリンクが張られているかは一目瞭然だ。
 では、具体的に見てみよう。CGIプログラムで記述する場合、呼び出し側のHTMLでは、次のように記述する。

[呼び出し側HTML]
 <A HREF="/cgi-bin/locat1.cgi">おまけ</a>
 <A HREF="/cgi-bin/locat2.cgi">ふうばあ会社</a>
 <A HREF="/cgi-bin/locat3.cgi">花もげら株式会社</a>

「/cgi-bin」には、CGIプログラムを置くディレクトリを指定する。また、locat1〜locat3.cgiは、それぞれ次のようになる(シェルスクリプト)。


[locat1.cgi]
 #!/bin/sh
 echo "Location: /~nohoho/omake.html"
 echo


[locat2.cgi]
 #!/bin/sh
 echo "Location: http://foo.bar.co.jp/"
 echo


[locat3.cgi]
 #!/bin/sh
 echo "Location: http://hana.mogera.co.jp/index.html"
 echo

 それぞれのサンプルプログラムの3行目の echo だけの行は、先に説明したCGIプログラムが返す最初のヘッダと、データの境界を示すための空行を出力する。

・Status:
 Statusヘッダは、CGIプログラムで画面をそのままにした状態で、データを受け取りたいときなどに使用される。
 WWWサーバとブラウザに、特別な状態コードを返すときに用いられる。状態コードは、WWWサーバである HTTPD の仕様で決められている。例えば、次の行は、サーバから応答がなかったことを意味する。

   Status: 204 No Respnse


簡単なCGIプログラム

 自分のホームディレクトリに置いてあるファイルのリストを出力するサンプルとGIF画像を出力するサンプルを作ってみよう。

・ファイルのリストを出力する


[呼び出し側HTML]
 <a href="/cgi-bin/ls.cgi">Sample CGI ls output</a>


[ls.cgi]
   #!/bin/sh
   echo "Content-type: text/html"
   echo
   echo "<HTML><HEAD>"
   echo "<TITLE>CGI Sample ls -l output</TITLE>"    
   echo "</HEAD><BODY>"
   echo "<PRE>"
   ls -l
   echo "</PRE>"
    echo "</BODY></HTML>"

 まずホームページで、呼び出すCGIプログラムを指定する。次のHTMLで記述する部分だ。

   <A HREF="/cgi-bin/ls.cgi">Sample CGI ls output</A>
 ここで「/cgi-bin」は、前述したとおりCGIプログラムを置くディレクトリである。
 次に本体のCGIプログラムを、自分のパソコンで作成する。もしWWWサーバ上に環境があれば、そこで直接作成することもできる。なお、「ls.cgi」の各行は、次のような意味になる。

[解説]
  1.  #!/bin/sh
     このCGIプログラムは、シェルスクリプト(Bシェル)で書かれている。  
  2.  echo "Content-type: text/html"   
     CGIプログラムが送出するデータ型を示すのに使われるContent-type:ヘッダで、「text/html」ならHTML形式で出力する意味となる。  
  3.  echo   
     空行の指定。出力ヘッダと出力データとの境界を指示するため、必ずつける必要がある。  
  4.  echo "<HTML><HEAD>"   
     HTMLファイルの始まりのヘッダを出力する。  
  5.  echo "<TITLE>CGI Sample ls -l output</TITLE>"
  6.  echo "</HEAD><BODY>"   
     タイトルを出力する。  
  7.  echo "<PRE>"   
     ファイルのリストを表示するのに「ls」コマンドがあるが、このコマンドの出力だけでは改行タグが挿入されないため、<PRE></PRE> の整形タグを使用する。  
  8.  ls -l   
     ファイルのリストを表示するUNIXのコマンド。SSI時刻の表示とアクセスカウンタ。  
  9.  echo "</PRE>"   
     整形タグの終了。  
  10.  echo "</BODY></HTML>"   
     HTMLの終了。
 以上を記述してファイルの作成が終わったら、FTPを使用して、ls.cgiをcgi-binディレクトリへ転送する。
 転送が終わったら、実行権をつけるために次のコマンドを忘れないように実行する。これはtelnetでアクセスし、次のコマンドを実行すればいい。

[実行権の付加]
 % chmod +x ls.cgi

 なお、telnetでアクセスすると、UNIXのコマンドを利用することになる。UNIXをまったく知らないと、ディレクトリを移動することもできない。
 そこで、次のようなコマンドはぜひとも覚えておいていただきたい。

コマンド 機 能 MS-DOSの同等コマンド
cat[file] ファイル内容の表示 type [file]
cd [dir] ディレクトリの変更 cd [dir]
chmod [mode][file] ファイル属性の変更 attrib [属性][file]
cp [file1][file2] ファイルのコピー copy [file1][file2]
echo [string] 文字列を返す echo
less [file] ページング more
logout ログイン終了 _
ls [dir] ファイル一覧 dir [dir]
man [command] コマンドのヘルプ ? [command]
mv [file1][file2] ファイルの移動 ren [file1][file2]
pwd 現ディレクトリ名の表示 cd
rm [file] ファイルの削除 del [file]
※[ ]内はファイル名やディレクトリ名、コマンドなど、指定されているものを指定する。


・GIF画像を出力する

[呼び出し側HTML]
 <a href="/cgi-bin/gif.cgi">Sample CGI GIF Image </a>

[gif.cgi]
  #!/bin/sh
  echo "Content-type: image/gif"
  echo
  cat sample.gif

[解説]
  1.  #!/bin/sh   
     このCGIプログラムは、シェルスクリプト(Bシェル)で書かれていることを示す。  
  2.  echo "Content-type: image/gif"   
     Content-type:ヘッダで、GIF画像形式で出力する旨を記述。  
  3.  echo   
     空行の指定。出力ヘッダと出力データとの境界を指示するため、必ずつける必要がある。  
  4.  cat sample.gif   
     sample.gif という名前のGIF画像を出力する。
 ファイルの作成が終わったら、FTPを使用して、gif.cgi をcgi-binディレクトリへ転送する。また、転送が終わったらtelnetでアクセスし、実行権をつけるために次のコマンドを忘れないように実行する。

[実行権の付加]
 % chmod +x gif.cgi


◆CGIプログラムへの引数渡し

 これまでのサンプルでは、コマンドを実行するだけであったが、引数をつけてプログラムを実行することもできる。
 引数は、CGIプログラムと引数の間を疑問符(?)で区切り、またそれぞれの引数の間をプラス記号(+)で区切って記述する。

[書式]
   <A HREF=/cgi-bin/cgiprg.cgi?引数1+引数2+引数3.....>

 ここでいう引数とは、もちろん指定したCGIプログラム、つまり上の書式でいえばcgi-binディレクトリの「cgiprg.cgi」というプログラムで指定できる引数のことだ。  この引数は、それぞれ利用するプログラムによって異なってくる。どんな引数がどのような機能を実現するものか、利用したいプログラムをよく知っておく必要もあるだろう。

◆CGIで使える環境変数

 CGIプログラムのなかでは、次のような環境変数を利用することもできる。これは「CGI変数」ともよばれるものだ。以下、CGI変数とその説明、さらに出力例を示しておこう。

CGI変数 出力例 説明
GATEWAY_INTERFACE CGI/1.1 WWWサーバが使用しているCGIのバージョンを表示する。
SERVER_PROTOCOL HTTP/1.0 HTTPプロトコルのバージョン。
SERVER_SOFTWARE NCSA/1.5 WWWサーバのプログラム名と、そのバージョン。
SERVER_NAME www.foo.bar.co.jp WWWサーバのホスト名、またはそのIPアドレス。
REQUEST_METHOD GE クライアント(WWWブラウザ)からの要求メソッド。ここに入るメソッドには、GET、POST、HEAD、PUT、DELETE、LINK、UNLINKがある。
SCRIPT_NAME /cgi-bin/test.cgi CGIスクリプトのパス名。
QUERY_STRING arg1+arg2+arg3 GETメソッド形式で実行されたときの引数が入る。?以下すべての引数が入るため、引数の参照をこの変数から行なうこともできる。
REMOTE_HOST nohoho.hana.mogera.co.jp CGIプログラムを実行したホスト名。
REMOTE_ADDR 111.222.123.95 CGIプログラムを実行したホストのIPアドレス。
HTTP_USER_AGENT Mozilla/3.0b6 (Win95; I) WWWブラウザの情報。この例では、Netscape Navigator 3.0Beta6を示している。
HTTP_REFERER http://nohoho.hana.mogera.co.jp/~nohoho/ 直前に参照していたURL。ただし、ブラウザによっては送らないものもある。
 CGIプログラムの実例は、プロバイダで提供されるCGIプログラムの使い方や、簡単なサンプル例の項を参考にして欲しい。




◆SSIを使う

 SSIは、前述したようにプロパイダによっては使用を制限しているところも少なくない。使用する前に、まず自分のホームページを置いているプロバイダで、SSIが使用できるかどうか確認する必要がある。また、SSI は、NCSA WWWサーバ上で、次のどちらかの拡張子を定義している。
   text/x-server-parsed-html .html
   text/x-server-parsed-html .shtml
 つまり、SSIを使用したページの拡張子が、「.html」になるのか「.shtml」になるのかを、WWWサーバの管理者に確認しておく必要もあるだろう。.shtmlと定義されているのに、SSIスクリプトを記述したHTMLファイルの拡張子を.htmlとしていたのでは、いくら正しくスクリプトを記述していても認識されないので注意。

◆SSIの一般形式

 SSIの記述形式は、次に示すようにHTMLのコメントを拡張したものと思えばいい。
   <!--#コマンド  タグ1="値1"  タグ2="値2"
 まずコマンドだが、これには次のようなものがある。

・#Config……出力形式の指定
 #Configコマンドは、SSIを使用したときの出力形式を指定するもの。主なオプションとして、次のようなものが利用できる。
sizefmt
ファイルサイズの単位を指定する。sizefmtの引数には、次のものがある。
bytes … バイト単位の正確な値を出力。
abbrev … Bytes, Kbytes, Mbytes 単位で、値を丸めて出力。
errmsg
エラーが発生したときの出力メッセージの設定。
timefmt
日付のフォーマットを指定する。timefmtの指定は、次表のようになっている(出力例は、1996年8月10日(土曜日)18時44分56秒とする)。
指定子 出力例 補 足
%x 08/10/96 _
%X 18:44:56 _
%c 08/10/96 18:44:56 _
%y 96 _
%Y 1996 _
%b Aug 3文字の略
%B August _
%m 08 _
%a Sat 3文字の略
%A Saturday_
%d 10 10日
%j 223 1月1日からの日数
%w 6 日曜日からの日数
%p PM _
%H 18 24時間
%I 06 12時間
%M 44 44分
%s 56 56秒.
%Z JST タイムゾーン

 timeftpの例として、ここでは次のように指定してみよう。


  <!--#config timefmt="%H:%M:%S"-->
  <!--#echo var="DATE_LOCAL"-->

 先の表ですでにおわかりのことと思うが、こう記述すると、次のような出力が得られる。

    18:44:56
 また、config timefmt が指定されない場合は、デフォルトで次のような出力となる。

    Saturday, 10-Aug-96 18:44:56 JST
・#include……他のファイルの取り込み
別の文書を挿入する場合には、#includeコマンドが使用される。次の例文を見ていただきたい。

  <!--#include vitrual="/~nohoho/bunsho.html"-->
 #includeコマンドのオプションvirtualには、DOCUMENT_ROOTパスを使用する。
 <!--#include virtual= ... > は、作成したすべてのページに同じ文字列、たとえば署名などを挿入するのに便利だ。これを利用すれば、署名用の別ファイルを変更するだけで、すべてのページに変更が反映されるからだ。
 また、fileオブションもある。こちらは、SSIを記述したファイルと同じディレクトリか、あるいはそれ以下のディレクトリに置いてあるファイルを取り込むときに使用する。

  <!--#include file="yahho.html"-->
 この指定の場合、同一ディレクトリ内にあるyahho.htmlファイルを取り込むことになる。fileオプションの指定では、同一ディレクトリか下位のディレクトリのファイルを指定するため、./ や ../ は指定してはいけない。

・#echo……環境変数の出力
#echoコマンドは、現在時刻や最新更新日、あるいはファイル名などといったHTTPの環境変数を出力する際に利用される。
 次のような記述を、HTMLファイルに書き込む。

  現在の時刻は、<!--#echo var="DATE_LOCAL"-->なのだ〜
 DATE_LOCALは現在時刻を出力する環境変数だが、これは#configコマンドのtimefmtオプションで指定されたフォーマットによって出力される。たとえば、#configコマンドで、<!--#config timefmt="%H:%M:%S"-->>指定されていれば、環境変数DATE_LOCALの値が#echoコマンドの引数varに渡され、

  現在の時刻は、18:44:56なのだ〜
 という具合に表示されることになる。
 また、次の例では、環境変数LAST_MODIFIEDを使い、HTMLファイルの最新更新日を出力している。

  <!--#config timefmt="%Y/%m/%d"-->
  このページは、<!--#echo var="LAST_MODIFIED"--> に更新されました
 いうまでもないが、#Configコマンドのtimefmtオプションで指定された書式("%Y/%m/%d")によって、このSSIが書かれたページを開くと、
  このページは、1996/08/10 に更新されました
 という表示が出力される。実際に画面で確認してみていただきたい。

・#fsize……ファイルサイズの出力
指定したファイルのサイズを出力するコマンドである。
 たとえば、ちょっと大きめの画像ファイルを置いていたり、あるいはフリーソフトや圧縮ファイルなどを置き、これをダウンロードできるようにしてあった場合、実際にダウンロードされるファイルのサイズが表示されているほうが親切というものだ。こんなとき、直接ファイルサイズを記述するのではなく、SSIによってファイルサイズを出力させてしまうといい。
 なお、出力されるファイルのサイズの単位は、#configコマンドのsizefmtオプションで指定されたものになる。
 たとえば、sample.lzhというファイルをダウンロード用に置き、このファイルのサイズをSSIで出力させてみた。

    <A HREF="sample.lzh">Sample.lzh</A>:<!--#config sizefmt="bytes"-->
    <!--#fsize file="sample.lzh"--> bytes)のダウンロード<BR>
    <A HREF="sample.lzh">Sample2.lzh</A><!--#config sizefmt="abbrev"-->
    <!--#fsize file="sample.lzh"--> B)のダウンロード<BR>

・#exec……コマンドやプログラムの実行を促す
シェルコマンドや、CGIプログラムを実行するコマンド。オプションにはcmd、cgiのいずれかを指定でき、cmdはシェルコマンドを、cgiではCGIプログラムをそれぞれ実行する場合に指定する。
 たとえば、次のように指定する。

  <!--#exec cmd="/usr/bin/ls"-->
  <!--#exec cgi="test.cgi"-->
 1行目の記述では、#execコマンドのオプションとしてcmdが使用されている。シェルコマンドを実行するときのオプションだ。
 2行目の記述は、#execコマンドのオプションとしてcgiが使用されている。こちらはCGIプログラムを実行するときのオプション。
 実際に、次のようなHTML文書を作成して実行してみてほしい。

    <HTML>
    <H3>
    <!--#exec cmd="ls"-->
    </HTML>

◆SSIで使う環境変数

 これまでに、DATE_LOCALやLAST_MODIFIEDなど、いくつかの環境変数を使用した例文を紹介してきた。もっとバリエーションを広げるために、ここでSSIで使用できる環境変数の主なものと、その出力例を紹介しておこう。

環境変数出力例説明
DOCUMENT_NAME ssi.html SSIを実行しているファイル名
DOCUMENT_URI /~nohoho/ssi.html ファイルの仮想パス
QUERY_STRING_UNESCAPED (none) 使えなかったコード(エスケープ文字など)
DATE_LOCAL Saturday, 10-Aug-96 20:25:27 JST ローカルタイムゾーンの日時
DATE_GMT Saturday, 10-Aug-96 11:25:27 GMT GMT(グリニッヂ標準時) の日時
LAST_MODIFIED Saturday, 10-Aug-96 20:25:18 JST 最後にファイルを更新した日時



[目次]

Copywrigth (C) 1996 by Kazumi Takei. All Rights Reserved.