CGIでリファラ(HTTP_REFERER)を取る方法  [perl]  [javascript]  [tips]

あいかわらず、初歩的なところにいます。。。(-_-;)
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を転送して終了。
なんか美しくないけど、動く。