CGIの仕組み

 PerlにしろC言語にしろ、CGIスクリプトを作るにはまずCGI自体の仕組みについて理解していなくてはいけません。掲示板などのCGIスクリプトは、Webページのフォームから送られて来たデータを処理し、Webページを生成してクライアントのプラウザに返します。では、この一連の処理の流れについて簡単に説明して行きましょう。うちのサーバーはTurboLinuxなので、説明は当然UNIXベースになります。ご了承下さい。

フォームから送られるデータ

 フォームからWebサーバーにデータを送る方法は、GET方式POST方式の2種類があります。GET方式で送られたデータは、サーバーによって環境変数QUERY_STRING」に格納されます。ただし、QUERY_STRINGに格納できる文字列の長さには制限があり、余り長い文字列は送る事が出来ません。一方、POST方式で送られたデータは標準入力(STDIN)からスクリプトに渡され、データのバイト数が環境変数CONTENT_LENGTH」に格納されます。

 

URL         データ部分(URLの一部として送られる)

GETの場合

http://<hostname>/~***/***.htm?value1=***&value2=***

−−−−−−−−−−−−−−−−−−−→
−−−−−−−−<Internet>−−−−−−−−
 

URL

Web Server

POSTの場合

http://<hostname>/~***/***.htm

 
−−−−−−−−−−−−−−−−−−−→
−−−−−−−−<Internet>−−−−−−−−
−−−−−−−−−−−−−−−−−−−→
 

value1=***&value2=***

Web Server
 

データ部分(標準入力として送られる)

 

又、これらのどちらの方法を使っても、データの内容は一旦エンコードされてしまいます。

URLエンコーディング

 Webブラウザがフォームの入力データをWebサーバーに送り出す時は、ある一定の法則で符号化してWebサーバーに送ります。これを「URLエンコーディング」と言います。

 URLエンコーディングは、Webブラウザがフォーム内に入力された名前を取り出して、全てを一行のデータにしてから送ります。送る時の経路は、HTMLの<FORM>要素のmethod属性の値をGETPOSTのいずれにしたかで異なり、GETの場合はURLの一部として、そしてPOSTの場合は別の通信路を使って送られます。

◆URLエンコーディングの規則

1)「名前」と「値」は「=」でつながれる。フォームに値が入力されなかった場合は、値は空っぽのまま送られる。

2)複数の「名前」と「値」の組み合わせは「
&」でつながれる。

3)
7ビットASCII文字でないもの(特殊文字)は、「%」とそれに続く16進数2桁の文字列に変換される。「=」、「&」、「%」がフォーム内の値に入力された場合は、これも特殊文字として扱われる。

4)入力中の
スペースは「+」に変換される。

 尚、日本語などは7ビットASCII文字列ではないので、文字自体もエンコードされてしまいます。例えば、フォームでvalue1に「パール」、value2に「ソフトバンク」と入力したものは、以下のようにエンコードされます。

value1=%83p%81%5B%83%8B&value2=%83%5C%83t%83g%83o%83%93

フォームデータのデコード

 フォームに入力されたデータは、Webサーバーに渡る時に必ずエンコードされていますから、CGIスクリプトでこのデータを元に戻さなくては行けません。Perlにはこの為の定型処理コードがありますので、それを使ってデコードしてやってもいいですし、フォームのデータをデコードするPerlのツール群の一つである「cgi-lib.pl」ライブラリを使ってもいいでしょう。

 cgi-lib.plは以下のサイトから入手して下さい。

http://cgi-lib.berkeley.edu/

(1)デコードの為の定型処理コードは、以下のようになります。(掲示板スクリプトの例)

@pairs = split(/&/,$QUERY_DATA);
foreach $pair (@pairs) {
($key, $value) = split(/=/, $pair);
$value =~ tr/+/ /; ←「+」をスペースに変換
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; ←特殊文字処理
$value =~ s/</&lt;/g; ←以下はタグの処理
$value =~ s/>/&gt;/g;
$value =~ s/\n//g;
$value =~ s/\,/,/g;
&jcode'convert(*value,'sjis');
#分解したデータを連想配列に格納
$QUERY{$key} = $value;

(2)「cgi-lib.pl」ライブラリを使う場合は、CGIスクリプトの2行目以降でrequireしてやります。

#!/usr/bin/perl

#セッティング
require '../cgi-lib.pl'; ←相対パス使用
require '../jcode.pl'; ←相対パス使用

&ReadParse(*input_data);

 ここに出てきているReadParseルーチンは、フォームから送られてくるエンコードされたデータを受け取り、「名前」と「値」の組を、「名前」をキーにして連想配列に格納してくれます。このルーチンはGETとPOSTの両方に対応しており、とても有用です。

 このReadParseルーチンの呼び出しは、上の例にもあるように、

&ReadParse(*input_data);

と言う風に書きます。( )の中は好きなように変えられます。又ここからデータを取り出すには、この場合、

$input_data{'value1'} ・・・「value1」をキーにして「値」を取り出す場合

と言う風にします。

日本語の問題

 現在Webページで使われている文字コードには、大きく分けて3つあります。それはEUC(UNIX系)とJIS(日本工業規格)とシフトJIS(Microsoft社開発)です。もしこれらの文字コードが混在してしまうと、当然文字化けの原因になりますから、フォームから入力されたデータの文字コードを、出力する前に変換しておく必要があります。

 この問題を解決してくれるライブラリとしては、皆さんご存知の「jcode.pl」が有名です。「jcode.pl」は、文字コードの変換、半角カナから全角カナへの変換、日本語文字の置換と言った事をしてくれます。呼び出し方は、上記の通りです。

 文字化けの問題を避ける為には、取り敢えず特殊文字や半角カナなどを使わない事です。この事は、昨今では電子メールなどで大きな問題になっているようです。

 jcode.plは以下のサイトから入手して下さい。

ftp://ftp.iij.ad.jp/pub/IIJ/dist/utashiro/perl/

 

HOME

次へ 環境変数