質問:ブラウザで文字を入力し,これをCGIが受け取って処理する場合,アルファベットを入力しているときは正しく動作するのに,日本語を入力すると正しく動作しない(文字化け等がおきる).

この問題は,日本語文字の表現方法の食い違いにより起こります.日本語文字の表現方法として,JISコード,シフトJISコード,EUC(Extended Unix Code)コード,Unicode等いろいろな表現方法があります.ブラウザでは,それを自動的に認識してどんな表現方法でhtmlデータが送られてきても正しく表示されるように頑張るのですが,htmlデータの中に複数の表現方法が混在すると,おかしな表示が出てきます.

上記質問の現象は,通常のCGIの出力がEUCコードであるときに,ブラウザから入力させた文字が例えばシフトJISコード等EUCコード以外のコードであることが原因として考えられます.

対処方法は,表現方法の混在をなくすことにつきます. 具体的には,ブラウザから入力させた文字をEUCコードに変換しましょう.

変換は,既に変換するライブラリが用意されています(このように多くの便利なライブラリを多くの方が作成してそれを使えるのもPerlの特徴です)ので,そのライブラリを使いましょう.

ライブラリは,これまでは cgi-lib.pl というものを使っていました. この時は,プログラムの先頭の方でつぎのようにしてこの cgi-lib.pl を指定していました.

use lib '/home/httpd/cgi-bin';
require 'cgi-lib.pl';

これに加えて,今回 jcode.pl というものを使いますから,この部分は次のように変更します.

use lib '/home/httpd/cgi-bin';
require 'cgi-lib.pl';
require 'jcode.pl';

これで,文字変換を行うライブラリを使うことが出来ます. 実際に文字変換は,関数jcode::convertを使って次のように行います.

&jcode::convert($yourname, "euc") ;

この例は,変数 $yourname に入っている文字列を EUCコード に変換するものです.
これを組み込んで,例えば4.2章のCGIは次のようになります.

#!/usr/bin/perl
#初期設定
use lib '/home/httpd/cgi-bin';
require 'cgi-lib.pl';
require 'jcode.pl';
$|=1;
# 送信されたデータの取り込み
&ReadParse(*in_data);
$yourname = $in_data{'yourname'};
# 入力データのチェック
if($yourname eq "")
{
  print "Content-type: text/html\n\n";
  print "<HTML><BODY BGCOLOR=\"YELLOW\">\n";
  print "名前がブランクです。\n";
  print "</BODY></HTML>\n";
  die "入力エラー\n"; #処理を強制終了
}
# データ変換
&jcode::convert($yourname, "euc") ;
$yourname =~ s/\s*//g; #空白文字の削除
$yourname =~ tr/A-Z/a-z/; #ユーザ名を小文字に変換

#ブラウザへのメッセージ出力
print "Content-type: text/html\n\n";
print "<HTML><BODY BGCOLOR=\"YELLOW\">\n";
print "<H1 ALIGN=CENTER>$yournameさん、がんばりましょう。</H1>\n";
print "</BODY></HTML>\n";
__END__