買い物かご 掲示板 メール DB 利用規定 FAQ サポートBBS


次(送信データの表示)
前(変数の設定と変更)
必要なツール
最低限必要な知識
Make CGI Top
Basic

Home



デコード --最低限必要な知識--


送信データとエンコード

フォームを作成するときは、
<form method=POST action=xxx.cgi>〜</form>
を使うことはご存知ですね。

データはどのようにCGIへ送られるのでしょうか?

氏名 <input type=text name=name>
年令 才<input type=text name=age>
住所 <input type=text name=address>


というフォームがあり、 氏名「Taro Yamada」 年令「25」 住所「Tokyo」 と入力したとします。このデータは「test.cgi」に送信されるとします。

この場合、表には出てきませんが、
http://www.xxx.ne.jp/cgi-bin/test.cgi?name=Taro+Ymada&age=11&address=Tokyo
の形式で送信されます。

name=valueの形式で送信され、それぞれのオプションは「&」で区切られています。
スペースは「+」に変換されます。

では次の場合はどうでしょうか?

氏名 <input type=text name=名前>
年令 才<input type=text name=年令>
住所 <input type=text name=住所>


というフォームがあり、 氏名「山田太郎」 年令「25」 住所「東京都」 と入力したとします。このデータは「test.cgi」に送信されるとします。

この場合は、http://www.xxx.ne.jp/cgi-bin/test.cgi?test.cgi?%96%BC%91O=%8ER%93c%91%BE%98Y&%94N%97%DF=25&
%8FZ%8F%8A=%93%8C%8B%9E%93s

の形式で送信されます。純然たる英語では、意味がわかるアルファベットで送信されましたが、日本語では%に始まる記号に変換されてしまいます。このように、半角英数字以外の文字列を、%に始まる記号に変換することをエンコードすると言い、CGIスクリプトで、エンコードされた文字を元の日本語に戻す処理を行なうことをデコードするといいます。

日本語がどのようにエンコードされるのか見たい場合は、<form method=GET action=xxx.cgi>〜</form>に変更してみましょう。


■確認用フォーム(下のテキストボックスに適当な文字を入力します)

氏名 <input tye=text name=名前>
年令 才<input type=text name=年令>
住所 <input type=text name=住所>

テキストボックスに適当な日本語を入力し送信してみてください.
test.cgiは存在しないので、エラーを表示しますが、ブラウザのアドレスバーを見ればどのようにデータが送信されるかがわかると思います。


CGIによるデコード処理

さて、今度は、CGIスクリプト(test.cgi)によるデコード処理を見てみましょう。ソースは、前回も使用した「Perl Editor」に登録されている「初期設定」を使います。

改行位置が若干異なりますが、スクリプトの動作上問題はまったくありません。

なお、ここで、配列とか連想配列、xx関数など、知らない言葉が出てくるかもしれませんが、そこで思考をとめないように。できれば、どんな意味なのかを自分で推理してみるのも一興です。後で意味を知ったとき、当たっていても外れていても、使い方を忘れることは決してないでしょう。

# 入力形式の設定 標準='POST' その他'GET'
# 登録ボタンを押して Method not implemented.. 等というエラーが出る場合は
# GET で試すこと
# GETの場合は不要な悪戯を受けてしまう環境になりますので、注意してください.
$method = 'POST';

中略

# フォームからのデータを取得
if ($method eq 'POST' && $ENV{'QUERY_STRING'} ne '') { &error('要求エラー','POSTかGETしか受け取れません。'); }

以上は、methodがPOSTで、直接スクリプトのURLを指定して起動しようとしたときにエラーメッセージを出してスクリプトを中止するための処理。

if ($method eq 'POST') { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});


以上は、methodがPOSTの場合の処理。
読み込まれたデータを変数$bufferに格納しています。
($bufferはここではじめて登場します)

@pairs = split(/&/, $buffer); }

ここで、split関数を使って、$bufferに格納されているデータを「&」で分割し、配列@pairsへ格納しています。
(配列@pairsはここではじめて登場します)

elsif ($method eq 'GET') { @pairs = split(/&/, $ENV{'QUERY_STRING'}); }


以上は、methodがGETの場合の処理。送られてきたデータを「&」で分割し、配列@pairsへ格納しています。GETでは、変数$bufferは存在しません。送られてきたデータを直接@pairsへ格納します。


else { &error('要求エラー','POSTかGETしか受け取れません。'); }

以上は、methodがGETでもPOSTでもなかったときの処理。エラーメッセージを出して処理を中止します。

# フォームからのデータを連想配列に格納
foreach $pair (@pairs)

{

配列@pairsの内容を、foreach関数を使って一つづつ取りだします。

($name, $value) = split(/=/, $pair);

split関数を使って、取り出した内容を「=」で変数「$name」と「$value」に分割します。
(変数$name,$valueは、ここではじめて登場します)

$name =~ tr/+/ /;

$nameに「+」が含まれていた場合、半角スペースに変換します。

$name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;

%から始まるエンコードされたデータを、通常の日本語に戻します。
この式は、そのまま覚えてしまいましょう。

$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;

同じようにして$valueのデータを処理します。

&jcode'convert(*name,'sjis');
&jcode'convert(*value,'sjis');

jcode.plを使用して、$name,$valueをSJISに変換します。
この式もこのまま覚えてしまいましょう。

# 入力データのチェック
# タグが入力されていれば、それを無効にする。&lt;などに置き換え表示してる

$value =~ s/</&lt;/g;
$value =~ s/>/&gt;/g;

正規表現のs//g;構文を使って、文字を置換している。

# 区切り文字の”,”があれば”,”に変換
$value =~ s/\,/,/g;


半角カンマを全角カンマに置換しています。

# 改行コードを<br>に変換(上からWin、Mac、Unix用の処理)
$value =~ s/\r\n/<br>/g;
$value =~ s/\r/<br>/g;
$value =~ s/\n/<br>/g;


これも、正規表現のs//g;構文を使って、文字を置換している。

# 連想配列に格納

$FORM{$name} = $value;

ここで連想配列に格納したことで、$FORM{'名前'}と指定すると山田太郎と表示できるようになります。

}

何も考えず、このソースをそのまま使用すれば、連想配列を使って、自由にフォームから送られてきたデータを自由に利用することができます。

以上が、デコードの基本的な処理の仕組みです。なお、Web裏業では、違った処理の方法を取っています。基本的には同じことをしているのですが、人によって処理の方法が異なることがありますので、興味があったら見比べてみてもいいでしょうね。

ちなみに、Web裏業の方法では、送られてきたデータの形式が「GET」か「POST」かを自動認識するので、必要に応じて両方を使い分けることが可能です。上記の方法では、どちらか一方の方式しか指定できません。

スクリプトの用途によって使い分けてください。



Web寺子屋 OGIPOGI E-mail:info@web-terakoya.net
Copyright© 2000-2001 OGIPOGI All Rights Reserved.