あいかわらず、初歩的なところにいます。。。(-_-;)
perlのCGIでアクセス解析のためにリファラ(訪れた人が前に見ていたページ)を取ろうとしてたのですが、検索サイトによって文字が化けたりしてたので、utf8に統一してみようということで、以下のようにしました。
- ページに埋め込むjavascript
<script language="JavaScript">
<!--
document.write('<img src="http://hoge.fuga.funya/access.cgi?rr=' + escape(document.referrer) + '" />');
// -->
</script>
imgタグ内でアクセス解析用のcgiを呼んでいます。cgi側でHTTP_REFERERを取ると、このスクリプトを入れたページ自身になるので、パラメータとしてrrにリファラを入れています。
- cgi側(perl)
#!/usr/bin/perl -w
use strict;
use CGI;
use Encode;
use Encode::Guess qw/euc-jp shiftjis 7bit-jis/;
use utf8;
my $file="access.log";
my $q=new CGI;
my $ref = url_decode($q->param('rr')); #前のページ
my $referer = url_decode($q->referer()); #見られてるページ
my $result="\"$ref\",\"$referer\"\n";
open(FILE,">>:encoding(utf8)", $file) or error($q, "can't open");
print(FILE $result);
close(FILE);
&printimg;
exit;
sub url_decode{
my $str = shift;
return 'hoge' unless $str;
$str =~ tr/+/ /;
$str =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack('H2', $1)/eg;
my $decoder = Encode::Guess->guess($str);
return $decoder->decode($str) if(ref($decoder));
return decode("utf8",$str);
}
sub printimg{
open(COUNTERIMG, "./counter.gif") or error($q, "can't open");
binmode(COUNTERIMG);
print "Content-type: image/gif\n\n";
print <COUNTERIMG>;
close(COUNTERIMG);
}
urlエンコードされた文字を一旦もどしてからEncode::Guessでデコードしてファイルに書き込んでいます。
これにより、文字コードが統一されます。
urlエンコードをデコードするときにpackを利用しているのでutf8フラグ関係が心配なので、utf8フラグをつける前にurlデコードしています。
最後にimgを転送して終了。
なんか美しくないけど、動く。
ツイート