IEでのURLエンコード

メールアドレスを変更するため、メールを使ったアクティベーションを行うとします。具体的にはこういう手順です。

  1. ユーザが新しいメールアドレスを入力
  2. アクティベーションコードとメールアドレスをURLに入れてユーザへメール
  3. ユーザがメール本文のURLをクリック
  4. アクティベーションを受け付けてメールアドレスを変更

具体例

こういうメールがユーザに届くとします。

satake7さん、メールアドレスを再設定するには、↓のURLを開いてください。
http://localhost:3000/reset_email/5c0xxx3be/mam%405%2D55%2Ejp

メールアドレスに該当する部分(mam%405%2D55%2Ejp)はエンコードされています。Railsのルートはこのようになっています。

map.reset_email '/reset_email/:code/:new_email',
:controller => 'change_emails', :action => 'show'

これを受け付けると、params[:code]に'5c0xxx3be'がセットされ、params[:new_email]に'mam@5-55.jp'がセットされるはずです。
Firefoxでは確かにそういう挙動をするのですが、IE7では Routing Errorになってしまいます。

原因と対処

IE7(7に限らないかもしれませんが)では、このURL(↓)は、

http://localhost:3000/reset_email/5c0xxx3be/mam%405%2D55%2Ejp

アドレスバーに入った時点で、こう(↓)なります。

http://localhost:3000/reset_email/5c0xxx3be/mam%405-55.jp

Railsでは、ピリオドの入ったURLを受け付けると Routing Errorになります。(静的なファイルを探しにいってるのでしょうか?)
IE側でURLを勝手にデコードしないような設定があるのかもしれませんが、デフォルトでデコードしてしまう限り、設定での対処は難しいので、こちらサイドでなんらかの対処をとらないといけません。
routes.rbをいじるとなんかうまい方法があるのかもしれませんが、試行錯誤の時間がもったいないので、URLを組み立てるときにピリオド(%2E)をカンマ(%2C)に置き換えることにしました。

http://localhost:3000/reset_email/5c0xxx3be/mam%405%2D55%2Cjp

これを受けると、params[:new_email]に'mam@5-55,jp'がセットされるので、ここで','を'.'に置き換えなおしています。ちょっと安直ですが、一番確実だと思います。