URLエンコード

CGIにパラメータとして文字列を渡す場合、そのままだと空白や&記号が使えないので、URLエンコードを使うことになる。
微妙に癖があって、しばらく迷ったのでメモメモ。

JavaScriptでのURLエンコード

わかりやすい名前のescape/unescapeはブラウザごとに実装が違うので、使わないほうがよい。
変わりにencodeURI/decodeURIかencodeURIComponent/decodeURIComponentを使う。この2つの関数の違いは、'/'などをエンコードするかどうか。ちなみに、Component系のほうがエンコードする。

<html>
  <head><title>TestPage</title></head>
  <body>
    <script type="text/javascript">
      var uri = 'みずの ひろき';
      document.write('<p>original:');
      document.write(uri);
      document.write('</p>');
      
      var encoded = encodeURI(uri);
      document.write('<p>encode:');
      document.write(encoded);
      document.write('</p>');

      var decoded = decodeURI(encoded);
      document.write('<p>decode:');
      document.write(decoded);
      document.write('</p>');
      
    </script>
  </body>
</html>

RubyでのURLエンコード

CGI.escape/CGI.unescapeを使うことでエンコード/デコードすることができる。

require 'uri'
uri = 'みずの ひろき'
print 'original:',uri,"?n"

encoded = URI.escape(uri)
print 'encode:',encoded,"?n"

decoded = URI.unescape(encoded)
print 'doceded:',decoded,"?n"

まとめ

上記2つのまとめとして、JavaScriptエンコードした文字列をRubyでデコードしてみることにする。

まずは、JavaScriptエンコードしてみる。アドレスバーに

javascript:encodeURI('みずの ひろき')

と打つとエンコードするとエンコードされた文字列が得られる。

%E3%81%BF%E3%81%9A%E3%81%AE%20%E3%81%B2%E3%82%8D%E3%81%8D

ほいで、Rubyでデコードしてみる。単純にCGI.unescapeしただけではUTF8文字列が得られるだけなので、文字コードを変換しないといけない。

require 'kconv'
require 'uri'
puts URI.unescape(ARGV[0]).tosjis

そうすると、

$ ruby decode.rb %E3%81%BF%E3%81%9A%E3%81%AE%20%E3%81%B2%E3%82%8D%E3%81%8D
みずの ひろき