ネットワーク 3 (CGI)

CGI とは

CGI(Common Gateway Interface)とは、Webブラウザから来た要求に対して、 WWWサーバでプログラムを起動する仕組みです。
これによって、入力データによって変化するWebページや、ファイルやデータベースにデータを保存するような処理を実行できるようになります。
サーバ側で起動されるプログラムは、標準入力から入力可能で、 標準出力に出力可能なものなら、 どんな種類のプログラム言語を使用しても作成できます。 実際は、CGI作成用としてPerl、Ruby、Pythonなどのスクリプト言語が良く使われます。

CGIの処理の流れは、以下のようになっています。

  1. ブラウザのフォームなどから、データがサーバに送られます。
  2. サーバは、CGIのプログラムを起動し、CGIプログラムは標準入力からデータを読み込みます。
  3. CGIプログラムは、計算・データベースなどの処理を行なった後、HTMLなどのブラウザが読み込むことのできる形のデータを標準出力に出力します。
  4. 出力されたデータが、サーバによってブラウザに送られます。

CGIを試すための準備

CGIを試してみるためには、CGIが使用できる設定がなされたWWWサーバが起動されている必要があります。
通常は、Apacheなどを使用しますが、ここでは簡単に実験するためにPythonによってシンプルなWWWサーバを起動しておきます。

  1. cgi-binという名前で、ディレクトリを作成しておきます。
    mkdir cgi-bin
    実行されるCGIのファイルは、このディレクトリの中に作成し、実行可能にしておきます。
  2. cgi-binディレクトリを作成したディレクトリで、以下のコマンドを実行してWWWサーバを起動しておきます。
    python -m CGIHTTPServer

CGIの例1

入力データの無い、文字列を表示するだけのシンプルなCGIを作成します。

プログラム解説

#!/usr/bin/python
このスクリプトを実行するPythonのパスを表します。
環境に合わせて、このパスは変更する必要があります。
print "Content-Type: text/plain"
ヘッダを出力します。
Content-Typeは送信されたデータの内容を表します。
text/plainは、テキストを表します。
HTML文書の時は text/html になります。
print
空行を出力します。
ヘッダと、本文の間には空行が必要です。
print "hello world"
本文として、hello worldを出力します。

CGIの例2

現在の日時を得るCGIを、HTMLデータによって表示してみます。

プログラム解説

# -*- coding: utf-8 -*-
ファイル中の文字コードとして、utf-8を指定します。
html = '''Content-Type: text/html
ヘッダと本文を文字列として作成しています。
この行の後の空行は、ヘッダと本文を分けるために必要です。
送信するデータはHTMLです。
'''は改行を含んだ文字列を表します。 次に、'''が出てくるまでが一つの文字列です。
その文字列を変数htmlに代入しておきます。
import time
時間を扱うためのtimeモジュールをインポートします。
now = time.strftime('%Y/%m/%d %H:%M:%S')
strftimeメソッドにより、現在の年・月・日・時間・分・秒を文字列として取得し、 変数nowに代入します。
print html % now
文字列htmlに含まれている%sの部分に文字列nowを当てはめて出力します。

CGIの例3

3つのボタンのうち、どのボタンが押されたかを表示するCGIを作成してみましょう。

プログラム解説 (test3.html)

<form action="cgi-bin/test3.cgi" method="post">
入力フォームを作成します。
入力フォームによって、サーバにデータを送信することができます。
actionによって、データの送信先、 methodによって、送信方法を指定できます。
methodの送信方法は、以下のとおりです。
post
本文としてデータ送信
get
URLの末尾にデータを追加して送信
<input type="submit" name="botton1" value="1" />
inputは、入力を受け付けるためのコントロールを作成します。
typeは、入力方法の種類を表します。
typeの種類は、以下のとおりです。
text
文字列を入力するフィールドを作成します。
submit
ボタンを表示します。
nameには、他のコントロールと区別するための名前を指定します。
valueは、このボタンを押したときにサーバに送られる値になります。
<input type="submit" name="botton2" value="2" />
botton2という名前で、値が2のボタンを表示します。
<input type="submit" name="botton3" value="3" />
botton3という名前で、値が3のボタンを表示します。
</form>
入力フォームの終わりです。

プログラム解説 (test3.cgi)

import cgi
cgiモジュールをインポートします。
cgiモジュールには、CGIデータを扱うためのクラス・メソッドが入っています。
f = cgi.FieldStorage()
FieldStorageクラスのインスタンスを作成します。
このインスタンスの中に、送られたデータが入っています。
if f.getfirst('botton1'):
getfirstメソッドによって、botton1ボタンが押されたかどうかを調べます。
b = '1'
botton1が押されていれば、変数bに'1'を代入します。
以下、同様にbotton2, botton3と調べてゆきます。
print html % b
文字列htmlの%sの部分に、押されたボタンの番号を当てはめて表示します。

CGIの例4

テキストフィールドに入力された文字列を表示するCGIを作成してみましょう。

プログラム解説 (test4.html)

<input type="text" name="text" />
テキストフィールドを表示します。
このテキストフィールドの名前はtextです。
<input type="submit" />
submitボタンを表示します。
このボタンを押すと、サーバにデータを送ります。

プログラム解説 (test4.cgi)

txt = f.getfirst('text', '')
テキストフィールドtextに入力された文字列を変数txtに代入します。
print html % cgi.escape(txt)
escapeメソッドは、txtに含まれるHTMLで表示できない文字を、表示できるように変換します。 変換された文字列を、htmlの%sに当てはめて表示します。

CGIの例5

ファイルをアップロードし、ブラウザに表示するCGIを作成してみます。

プログラム解説 (test5.html)

<form action="test14.cgi" method="post" enctype="multipart/form-data">
データをMIMEのマルチパートデータとしてサーバに送ります。
ファイルをアップロードして、送信するときには必要です。
<input type="file" name="file" />
ファイルを選択するための、テキストフィールドとボタンを表示します。

プログラム解説 (test5.cgi)

if form.has_key('file'):
fileという名前の、コントロールが存在するかどうか確かめます。
item = form['file']
fileから、FieldStorageクラスのインスタンスを作成し、変数itemに代入します。
if item.file:
ファイルのデータが存在するかどうか確認します。
data = item.file.read()
ファイルのデータを読み込んで、変数dataに代入します。

Prev
index | home
abetmhr@gmail.com