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属性の値をGET、POSTのいずれにしたかで異なり、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は以下のサイトから入手して下さい。
(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/</</g; ←以下はタグの処理
$value =~ s/>/>/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は以下のサイトから入手して下さい。
次へ 環境変数 |