CGIとは

IT

-概要-

CGIはCommon Gateway Interfaceの略で、ブラウザの要求に対してサーバーが別プログラムを起動して実行し、その結果をブラウザに返すためのインターフェースの事です。このインターフェース規格を使ってブラウザにhtml文を表示したり、ブラウザから受け取ったデータを加工したりするプログラムがCGIプログラムです。CGIプログラムの事をCGIスクリプトとも呼びます。

「スクリプト」とは直接OSのもとで実行されるプログラムではなくて、どこかにスクリプトをコンパイルする別の実行ファイルが有り、このプログラムがコンパイル(コンピューターが解釈できる言葉に変換する事)しながら、あるいは起動した後にコンパイルしてから実行させるプログラムの事を指すか、OS特有のコマンドをならべたものを指す場合が多いようです。後者はシェルスクリプトと呼ばれます。こういう意味でJavaScriptやVBScriptは一般的にブラウザがコンパイルしますから「ブラウザサイドスクリプト」、Perl言語で書いたCGIプログラムはサーバーマシンに入っている「Perl」というインタプリタがコンパイルしながら動作させるので「サーバーサイドスクリプト」と呼ばれる事が有ります。

CGIが出力するのはhtml文つまりホームページの内容そのものですから、ブラウザから送られてきたデータによってホームページの内容を動的に変化させられるわけです。これがCGIによるインタラクティブ性の本質です。又CGIプログラムはサーバーマシン側で実行されますから、サーバーのファイルにアクセスするようなプログラムを書く事ができます。掲示板やチャットのように発言メッセージをファイルに保存しておく必要の有るアプリケーションには最適です。逆に言えばJavaScriptやVBScriptでは原則としてサーバーマシン内のファイルにはアクセス出来ないのです。

また、ORACLEやPostgreSQL、MySQLといったDBMS(DataBase Management System)との連携で

クライアント(ブラウザ) — WebServer — ServerSideProgram

という構成からなるシステムを「3層クライアントサーバーシステム」と呼んだりします。

話は外れますが、サーバーマシンで実行されるWeb連携プログラムは何もCGIだけでは無く他にも有ります。MicroSoftのWindows + IISというサーバー環境であれば「ASP(ActiveServerPages)」という仕組みを使うとサーバー側でJavaScriptやVBScriptが実行され、そのスクリプト内からAPIを呼び出したりするとサーバー内ファイルにアクセスできます。さらに、Linuxでよく使われるPostgreSQLやMySQLなどのデータベースにアクセスするプログラムを書くのに便利なPHP」という仕組み(Perlに似た独自言語)や、Java言語を記述言語とする「JSP」「ServletProgram」という仕組みも有ります。これらはいずれもサーバーマシン内にスクリプトエンジンが常駐するため、その都度Perlが起動されるCGIスクリプトよりも一般的にパフォーマンスに優れているといわれますが、対応するWebServerが限定されるのが普通です。

-言語-

CGIプログラムはサーバーが動作しているOSのもとで動きますから、そのOS上で動作するものでなければなりません。サーバー機のOS上で動くプログラムであれば言語は何でも構いません。但しウェブサーバーがCGIというインターフェースをサポートしていなければなりません。サポートしていないサーバーは最近は無いと思いますが、個人利用の場合セキュリティ上の観点から使用を許可していないインターネットプロバイダーも多い様です。許可していても制限を加えているプロバイダーもあります。
インターネットのWebサーバーが動くOSで多いのはUNIXですが、UNIX(or Linux)上で動くCGIプログラムで多く使われている言語は、以下の様になると思います。

Perl インタプリタ系のスクリプト言語。UNIX(or Linux)用「Perl」はフリーで簡単に入手可能。
sh,csh シェルスクリプト。UNIXのコマンドをならべてプログラムとする。
C,C++ GCCなどのUNIX(or Linux)用コンパイラーで事前コンパイルが必要

イントラネットではかなりの数になると思われるWindows系であれば、CGIプログラムで一般的に使われる言語は以下の様になりますが、現在はCGIよりは、IISに密に連携する.NET FrameWork系のASP.NETなどのWebプラットフォームの方が多いと思います。表には載せていませんが、C#やVB.NETでもCGIは書けるはずです。

Perl インタプリタ系のスクリプト言語。Windows用「Perl.exe」(ActivePerlやStrawberryPerl)はフリーで簡単に入手可能。
バッチ Windowsのコマンドラインで使用できるコマンドによるバッチプログラム
C,C++ VC++などWindows用コンパイラーで事前コンパイルが必要
VisualBasic Windows上で動くBasic言語。VisualBasicで事前コンパイルが必要

-CGIの呼び出し方法-

CGIプログラムは、当然WWWサーバーが実行権を与えているフォルダに置かなければなりません。そしてhtmlファイルからの呼び出し方法は以下の5通りぐらいあります。

  1. Aタグで直接呼び出す---リンク部分をクリックする
    <A HREF=”(プログラムがあるフォルダ名)/×××.exe”> 掲示板 </A>
  2. FORMタグを使う---ボタンを押す
    <FORM ACTION=”(プログラムがあるフォルダ名)/×××.exe” METHOD=”POST”>
  3. IMGタグを使う---CGIプログラムが対応している場合のみ
    <IMG SRC=”(プログラムがあるフォルダ名)/×××.exe”>
  4. FRAME SRCタグを使う
    <FRAME SRC=”(プログラムがあるフォルダ名)/×××.exe”>
  5. スクリプト言語で呼び出す---以下はJavaScript「onLoadイベントの例」
    <BODY OnLoad=”(プログラムがあるフォルダ名)/×××.exe”>
    又は
    <FRAMESET OnLoad=”(プログラムがあるフォルダ名)/×××.exe”>
  6. SSIの#execコマンドを使う---ページを開くだけで起動
    <!–#exec cgi=”(プログラムがあるフォルダ名)/×××.cgi”>

exeの部分はcgi(Perlなど)でもOKです。但し昔のWindows+IIS環境では拡張子登録が必要でした(IIS3.0やPWSではレジストリへの拡張子登録が必要でしたしIIS4.0は拡張子マッピングが必要でした)。
「プログラムがあるフォルダ名」はホスティングサービス利用の個人サイトの場合通常以下のような感じです。

UNIX系
http://(プロバイダーのドメイン名)/(個人IDに相当する記号)/CGI-BIN/(プログラム名)
Windows
http://(サーバー機のドメイン名)/Scripts/(プログラム名)

-データ送信と環境変数-

ブラウザからWebサーバーにデータを送信する方法には「GET」と「POST」の2通りあります。CGIプログラムは、POSTで送信されたデータは標準入力から取り出し、GETで送信されたデータは「QUERY_STRING」というCGI環境変数から取り出します。

ブラウザへの情報の返信(httpレスポンス)方法としては、一般的にウェブサーバーによって起動されたCGIプログラムが標準出力へ情報を出力するとウェブサーバーがそのデータをhttpセッション毎にブラウザに送ります。

POSTの場合サーバーに送られてくるデータのバイト数がCGI環境変数CONTENT_LENGTH」に格納されます。よってPOSTの場合この変数の値分のデータを標準入力から読み込みます。htmlのformタグを使用して送信データを定義しhtmlのformボタンなどを使って送信します。GETの場合は、CGIプログラム名の後に「?」を付けてその後に文字列(クエリー文字列)を付けて起動すると、この文字列データはGETとして送信されます。

一般的に大量データを送信する場合はPOST、小量のデータしか送信しない場合はGETという使い分けをします。多くは「?」に続くクエリー文字列をCGIプログラムの動作モードを決定するデータとして利用する場合が多いようです。なお、データのうち「&,=,%,+,日本語文字」は%とそれに続く16進数2桁にエンコードされて送信されてきますので、CGIプログラムはこれをデコードしてから使う必要が有ります。Perlであれば送信されてきたデータのデコード処理をパッキングしたPerl用のフリーモジュールを使ったり、CGI用の便利な専用モジュールを手軽に利用できます。PerlであればURI::EscapeCGI.pmという有名なモジュールを使えば、GETやPOSTで送られてきた情報を効率よく簡単に取り出すことができます。

CGI環境変数にはこの他にも、クライアントのブラウザ名がセットされているもの、クライアントのIPアドレスがセットされているもの、クライアントのホスト名がセットされているもの、要求方法(GETかPOSTか)を示すもの、等々いろいろありますがここでは説明を省きます。又この環境変数はサーバーソフトとOSに依存するので完全に標準セットが有るわけではありませんが、どんなサーバーソフトでもまず利用できる環境変数リストは、以下を参照してください。ここではRFCで規格として制定されている変数が載っています。
CGI Environment Variables from NCSA

 

※ここからは現在では利用されない古い情報です。

 以上はCGIにおけるブラウザとサーバー間のデータ受け渡しの一般的な概要ですが、ここでWindowsのWebサーバー上で動かすためのVBを使ったCGIプログラムの書き方について少し触れます。WindowsのWebサーバーIIS/PWSでもブラウザからのデータは環境変数にセットします。ちなみにNT4.0WorkstationについてくるPeerWebServerの環境変数リストはこちらです。これらを使ってCGIプログラムを作成できるわけです。VBでは「environ」関数を使ってこの環境変数を読めます。但し「QUERY_STRING」は「COMMAND」関数を使って取り出します。又ブラウザに表示させる文字列は標準入出力関連のAPI関数を使います。私はこの辺の処理をまとめたフリーのコードモジュールを以下から入手して利用しています。
KOU-GEN-SHA Software labs」←リンク切れていました

-CGIが出力するヘッダー-

CGIプログラムが出力するヘッダは3種類有り、この3種類のうちのどれかを必ず最初に出力しなければなりません。又、ヘッダーを出力した後は必ず空行を1行出力しなければなりません。これによりサーバーはヘッダーの終わりを認識します。空行が無いとサーバーエラーになります。以下ヘッダーについて簡単に説明します。

  1. Location
    Locationヘッダは通常の出力を行う代わりに別のファイルへアクセスします。出力する文は
    Location: /aaa/bbb/friend.htm
    のようにします。これは例えばブラウザからの送信データによって条件分岐して、ある条件を満たしたときのみファイルにアクセスログを保存してから指定のURLにジャンプする処理を書く時などに使用されます。検索サイトなどでよく「リダイレクトされようとしています。」というメッセージが表示されますが、これは一旦CGIプログラムを呼び出して、このヘッダーを使って別のURLにジャンプする時に出るメッセージです。つまり検索サイトではおそらくヒットしたサイトへジャンプさせる前に回数等をロギングしているのでしょう。
  2. Status
    Statusヘッダはサーバーの状態コードを指定して、ブラウザはその状態を判断して反応を変化させます。例として下のようにヘッダーを出力するとブラウザは画面の書き換えを行いません。CGIプログラムが意図的にブラウザの画面をそのままの状態にしておきたい時などに使用します。ユーザーフレンドリーな木目細かいプログラミングが出来るでしょう。出力文は
    Status: 204 No response
    状態コードは他にも有りますがここでは省略します。
  3. Content-type
    Content-typeヘッダはCGIプログラムがサーバー経由でブラウザにデータを送る際、それがどのようなデータかをサーバーに教えるためのものです。出力データがhtml形式である場合は、
    Content-type: text/html
    以下によく使われるContent-typeの種類を挙げておきます。

    内 容 content-type
    HTML text/html
    テキスト text/plain
    画像(gif) image/gif
    動画(mpeg) video/mpeg
    PostScript application/postscript
  4. image/gifは画像型のアクセスカウンタ用CGIプログラムでよく使われています。

Related Posts