日本語のエンコーディング

前に RJSでの日本語の扱いという記事を書いたけど原因がわかった。
JavaScript で日本語のパラメータをURLにセットしているんだけど、そこでエンコードしてなかったのが原因。

 url = "<%= url_for :action => "show_memos" %>?item_name=" + $('spending_item_name').value;

ここをエンコードするように変更する事でOKと思い以下のように修正。

 url = "<%= url_for :action => "show_memos" %>?item_name=" + escape($('spending_item_name').value);

ところが、IEから実行するとまたもやエラー。Webrick のログを見てみると、Opera からアクセスした時(encodeをつける前)とパラメータが違う。

Opera
192.168.0.1 - - [06/Nov/2006:19:38:34 JST] "GET
/test/show_memos?item_name=%E9%A3%B2%E3%81%BF%E7%89%A9 HTTP/1.1" 200 454
IE
192.168.0.1 - - [06/Nov/2006:19:49:05 JST] "GET
/deals/show_memos?item_name=%u98F2%u307F%u7269 HTTP/1.1" 400 315

どうも、エンコードの方式が違うようだ。しかも、応答が 「400 Bad Request」になる。
ぐぐってみると、どうも Webrick のバグのよう。WebrickUnicode (%uXXXX形式)にエンコードされたものを理解できていないようだった。

【メモ】URLのパラメータに日本語文字列が%u形式でエンコードされているものがあるとBad Requestエラーになるみたい。ちなみに%uHHHHはUTF-16のコードで,Javascriptのescape関数を使うと,これになる。

ma2の日記 - WEBrickには%uとか使えないの?

Webrick の方に手を入れるのは嫌なので、他に対応策を調べてみたら以下のようなのがあった。

%uXXXXでひっかかっているのではないかと思います。
escape()を使わずにencodeURI/decodeURIを
使うなどするとどうでしょう。

ruby-list:41781 - Re: Webrickサーバのリクエストについて

これを参考に escape() → encodeURI() を使えばうまくいくようになった。

url = "<%= url_for :action => "show_memos" %>?item_name=" + encodeURI($('spending_item_name').value);