JavascriptのURLエンコード

前回、前々回のエントリ
XvfbとFirefoxとImageMagickでWebページのサムネイルを自動生成する方法 - pomo123の日記
なんちゃってクローラーでURL漁り - pomo123の日記
でリンクを集めて、Webページのサムネイルを取得するところまでは自動的にできるようになったので、今度はブラウザ上でリンクにmouseoverしたときにサムネイルを表示する方法を考えて見ます。

サムネイル画像の配信方法

クエリに与えられたURLを変換してファイルを出力するようなCGIを実装してもいいのですが、セキュリティやらパフォーマンスやらいろいろ配慮しないといけないことが多いので、ページのURLをURLエンコードしたものをそのままディレクトリ名にしてWebサーバ上に置くことにします。これだと、直接的にWebサーバがサムネイル画像を提供できるので一番簡単な方法です。

Greasemonkey

ブラウザでリンクにmouseoverしたときにサムネイルを表示する手っ取り早い方法はやはりGreasemonkeyを使うものです。具体的には以下のような方法があるようです。
502 Bad Gateway
徒然ぶろぐ > Google とハテブのサムネイル表示 Greasemonkey
最速インターフェース研究会 :: livedoor ReaderにSimpleAPIのサムネイルを加えるGreasemonkeyスクリプト

URLエンコード

JavascriptでURLエンコードを行うには、escape, encodeURI, encodeURIComponentがありますが、
javascript: escape(), encodeURI(), encodeURIComponent() 比較 (groundwalker.com)
にあるように、変換結果に差があります。

前々回では、

sub URLencode {
    my $URLencode = shift;
    $URLencode =~ s/([^0-9A-Za-z_ ])/'%'.unpack('H2',$1)/ge;
    $URLencode =~ s/\s/+/g;
    return $URLencode;
}

のようにperl上でエンコードしましたが、この方法では、

http://hoge.com/
↓
http%3a%2f%2fhoge%2com%2f

となります。一方JavascriptのencodeURIComponent()関数を使うと、

http://hoge.com/
↓
http%3A%2F%2Fhoge.com%2F

となります。

この2つの変換結果は以下の点で異なります、

  • 16進数の大文字小文字
  • "."

これは、Webサーバで直接ファイル名を指定してサムネイルを提供する場合に問題となります。そこでperl側で以下のように修正することにしました。

sub URLencode {
    my $URLencode = shift;
    $URLencode =~ s/([^0-9A-Za-z_\. ])/sprintf("%%%02X", ord($1))/ego;
    $URLencode =~ s/\s/+/g;
    return $URLencode;
}

これでJavascriptのencodeURIComponent()の変換結果と同じになります。
#半角スペースの処理は明らかに違うのでまだ細かいところで調整が必要になりそう。

あとはGreasemonkey内でリンクのURLをencodeURIComponent()にかけて、サムネイル画像をおいてあるサーバにアクセスするようにすれば、所望の動作をするはずです。