トップ回答者
mailto 文字化け対応方法

質問
-
お世話になります。
「Outlook 2007」でmailtoをクリックするとメール文章が文字化けする現象があります。
mailto:のUTF-8サポートのためにおこった現象だと思われるのですが、
これまでも(outlook2003)、URLEncode()を使用してShiftJISに変換していたので、
新たにボタン(outlook2007移行の方)を設け対応することは簡単に見えたのですが、
半角スペースが、「+」になることがわかりました。
エンコードができないと「+」となり、それを%20にエンコードすることで対応できたのですが、
疑問があります。これまでは、ネット上でこのような対策をみつけ参考にして実装していたのですが、
なぜUrlEncode関数を使用しているのかがわからなくなりました。EcodingクラスやUTF8Encoding があるにも関わらず、なぜHttpUtility.UrlEncodeメソッドを使用しているのでしょう。EcodingクラスやUTF8Encoding を使用してみたのですが、半角スペース問題は起こりませんでした。
推測するには、いちいちBYTEの配列におとして使用するのが面倒だったのかと思うのですが、
何かほかにUrlEncode関数を使用する意図があったのでしょうか。
もしくわ、Endodingクラスなどを使用すると問題があるのでしょうか。教えてください。
回答
-
>半角スペースが、「+」になることがわかりました。
こちらは、URLEncodeメソッドの仕様になります。
http://msdn.microsoft.com/ja-jp/library/4fkewx0t.aspx の(解説)
>それを%20にエンコードすることで対応できたのですが、
空白を[+]ではなく[%20]でエンコードしたいということですよね。UrlPathEncode()で可能です。
デコードするプラットフォームやブラウザに関係なく、デコードされた URL の一貫性が
保証されるように URL のパス部分をエンコードするときには、UrlPathEncode() メソッドを使用します。
例)
// エンコードする文字列 string hoge = "ほ げ"; // UrlEncodeを使ってエンコード(内部文字コード) string encStr1= HttpUtility.UrlEncode(hoge); // UrlPathEncodeを使ってエンコード(内部文字コード) string encStr2= HttpUtility.UrlPathEncode(hoge); // 結果 //encStr1 => "%e3%81%bb+%e3%81%92" //encStr2 => "%e3%81%bb%20%e3%81%92"
>EcodingクラスやUTF8Encoding があるにも関わらず、なぜHttpUtility.UrlEncodeメソッドを
>使用しているのでしょう。
EcodingクラスやUTF8Encoding は、文字コードを変換する為のものです。
UrlEncodeは、文字コードの変換ではなく、URLでは使用できない文字を等価の文字エンティティに
変換する為のものです。
よって使用する用途が違います。
>URLEncode()を使用してShiftJISに変換していた
とありますが、恐らく以下のような感じと思います。
string encodedString = HttpUtility.UrlEncode(hoge, Encoding.GetEncoding("shift-jis"));
これは、簡単にいえば、URLエンコードする時に、第二引数で指定した文字のエンコードを行って
URLエンコードを行う、ということです。
http://msdn.microsoft.com/ja-jp/library/h10z5byc.aspx
なお、URLエンコードする場合は、必ずしもS-JISに変換してやるという決め事はありません。
その文字列を解釈(デコード)する側との疎通が取れていれば、EUCでもUTF8でもよいです。
- 回答としてマーク 山本春海 2010年11月15日 4:58
-
書かれている不具合は、
<a href="mailto:メアド?subject=件名"></a>
とした場合に、メール作成画面(各自のメーラー)に表示される件名が化けるという話ですかね?
C# のフォーラムに投稿された理由は、上記タグを出力しているのが ASP.NET(C#) で、件名部分の文字列を生成する際に Encoding と UrlEncode を使用されているということでよろしいでしょうか?
検索してみたのですが、化けるか化けないかはブラウザの種類やそのバージョン(およびメーラー)の実装に依存する話のようで、根本的な解決方法はないみたいでした。
昔は Shift_JIS のエンコードで UrlEncode しておくと化けない環境が多かったのかもしれませんが、今は違うのかもしれません。
次のサイトを見ると、mailto に関する RFC は存在していても不十分なようですね(十分に理解しないまま、ざっと読んでそう思っただけなので、間違ってるかもしれません)。http://suika.fam.cx/~wakaba/wiki/sw/n/mailto
確実なのは、mailto は使用せずに、メール送信画面を用意して System.Net.Mail.SmtpClient 等を使ってメールを送信するようにすることかなと思いました。
- 回答としてマーク 山本春海 2010年11月15日 4:58
すべての返信
-
>半角スペースが、「+」になることがわかりました。
こちらは、URLEncodeメソッドの仕様になります。
http://msdn.microsoft.com/ja-jp/library/4fkewx0t.aspx の(解説)
>それを%20にエンコードすることで対応できたのですが、
空白を[+]ではなく[%20]でエンコードしたいということですよね。UrlPathEncode()で可能です。
デコードするプラットフォームやブラウザに関係なく、デコードされた URL の一貫性が
保証されるように URL のパス部分をエンコードするときには、UrlPathEncode() メソッドを使用します。
例)
// エンコードする文字列 string hoge = "ほ げ"; // UrlEncodeを使ってエンコード(内部文字コード) string encStr1= HttpUtility.UrlEncode(hoge); // UrlPathEncodeを使ってエンコード(内部文字コード) string encStr2= HttpUtility.UrlPathEncode(hoge); // 結果 //encStr1 => "%e3%81%bb+%e3%81%92" //encStr2 => "%e3%81%bb%20%e3%81%92"
>EcodingクラスやUTF8Encoding があるにも関わらず、なぜHttpUtility.UrlEncodeメソッドを
>使用しているのでしょう。
EcodingクラスやUTF8Encoding は、文字コードを変換する為のものです。
UrlEncodeは、文字コードの変換ではなく、URLでは使用できない文字を等価の文字エンティティに
変換する為のものです。
よって使用する用途が違います。
>URLEncode()を使用してShiftJISに変換していた
とありますが、恐らく以下のような感じと思います。
string encodedString = HttpUtility.UrlEncode(hoge, Encoding.GetEncoding("shift-jis"));
これは、簡単にいえば、URLエンコードする時に、第二引数で指定した文字のエンコードを行って
URLエンコードを行う、ということです。
http://msdn.microsoft.com/ja-jp/library/h10z5byc.aspx
なお、URLエンコードする場合は、必ずしもS-JISに変換してやるという決め事はありません。
その文字列を解釈(デコード)する側との疎通が取れていれば、EUCでもUTF8でもよいです。
- 回答としてマーク 山本春海 2010年11月15日 4:58
-
書かれている不具合は、
<a href="mailto:メアド?subject=件名"></a>
とした場合に、メール作成画面(各自のメーラー)に表示される件名が化けるという話ですかね?
C# のフォーラムに投稿された理由は、上記タグを出力しているのが ASP.NET(C#) で、件名部分の文字列を生成する際に Encoding と UrlEncode を使用されているということでよろしいでしょうか?
検索してみたのですが、化けるか化けないかはブラウザの種類やそのバージョン(およびメーラー)の実装に依存する話のようで、根本的な解決方法はないみたいでした。
昔は Shift_JIS のエンコードで UrlEncode しておくと化けない環境が多かったのかもしれませんが、今は違うのかもしれません。
次のサイトを見ると、mailto に関する RFC は存在していても不十分なようですね(十分に理解しないまま、ざっと読んでそう思っただけなので、間違ってるかもしれません)。http://suika.fam.cx/~wakaba/wiki/sw/n/mailto
確実なのは、mailto は使用せずに、メール送信画面を用意して System.Net.Mail.SmtpClient 等を使ってメールを送信するようにすることかなと思いました。
- 回答としてマーク 山本春海 2010年11月15日 4:58