トップ回答者
IEでWebサイトからファイルをダウンロードする際にファイル名の日本語が文字化けする

質問
-
IE(IE8)でWebサイトからファイルをダウンロードする際にファイル名の日本語が文字化けします。
Webサイトからファイルをダウンロードする際には、以下のHTTPヘッダがWebサーバから送信されますが、
Content-Dis; filename="ファイル名"
この"ファイル名"はSjisでエンコードされた状態でクライアントに送信されています。
IEはこの"ファイル名"をSjisでエンコードしてあるものとして扱う仕様であるらしいので、問題なくダウンロードできるはずです。
全てのクライアントで文字化けするのではなく、特定のクライアントで文字化けが発生するので、どこかの設定が原因ではないかと考えているのですが、
お教えいただけると非常に助かります。
なお、Webサーバからの以下のHTTPヘッダで
Content-Dis; filename="ファイル名"
ファイル名をSjisではなくURLエンコードとした場合には文字化けすることなくファイルをダウンロードできます。
Content-Dispositionのファイル名がSjisの場合には文字化けが発生し、URLエンコードの場合には文字化けしません。
本来のIEの仕様と異なる動作のようですが、原因がわかりますでしょうか。
何卒よろしくお願い致します。
回答
すべての返信
-
まず、charsetとencodingは直交する概念です。「ファイル名がSjisの場合には文字化けが発生し、URLエンコードの場合には文字化けしません。」はchasert SJIS+無変換で文字化けし、charset ???+URL encodingした場合に文字化けしない、ということでしょうか。その際、使用されたcharsetに関して記述が抜け落ちています。
次に仕様面で、Content-DispositionなどはMIMEで規定されているものですが、実はMIME 1.0では仕様の漏れがあり、entityに対してのcharsetを指定することはできても、ヘッダー自身にはcharsetを指定する術がありませんでした。
結果として、各社独自の実装を行いE-Mailなどでも添付ファイルの文字化けなどを引き起こしています。
HTTPに於いてもMIMEを採用しているためそのまま同じ問題が発生します。IEではURLエンコードされていた場合にUTF-8と見なし、そうでない場合はOS言語に応じて解釈となっているようです。一応RFC5987でcharset及びエンコード方法が規定され、IE9でそれに対応していますが、これに未対応なクライアントは100%化けるためなかなか普及しづらいところです。
SJISでは中継するProxyサーバーが文字化けを引き起こす可能性もありますから(だからこそエンコーディングに関する仕様が必要だった)、UTF-8 + URLエンコーディングが無難な解ではないでしょうか。
-
> Content-Dis; filename="ファイル名"
というのは確かなんですか?
Content-Disposition: attachment; filename=... の間違いですか?
・・・と書いたんですが、全部の文字を半角で書くと、勝手に変えられてしまいますね(上記は : が全角です)。であれば、失礼しました。
- 編集済み SurferOnWww 2014年2月18日 16:25 一部訂正&追記
-
一口に文字化けと言われても、いろいろですから。どういう文字化けか説明してもらわないと分かりません。
utf-8をshift_jisで見た、とか。
同じie8で、となると、キャッシュの不具合でしょう。
- 編集済み ウィンドウズスクリプトプログラマ 2014年2月19日 12:03
-
皆様、ご返答誠にありがとうございます。
charsetとencodingについて詳細を記載します。
・文字化けするパターン:charset→Sjis、encoding→なし
・文字化けしないパターン:charset→Utf8、encoding→URLエンコーディング
です。
文字化けの仕方としては、Utf8の文字をSjisで開く際の化け方に似ています。
本来のIEの仕様としては、charset→Sjisで文字化けすることなく処理可能なはずであることと、
一部のクライアントのみで文字化けが発生していることから、クライアント側の設定等で解消したいです。
つまり、サーバ側で「charset→Utf8、encoding→URLエンコーディング」とすることでも回避は可能なのですが、
サーバ側は修正せず、クライアント側IEの設定変更等で解消したいです。
何卒、アドバイスの程よろしくお願い致します。
-
文字化けの仕方としては、Utf8の文字をSjisで開く際の化け方に似ています。
似ていますって何でしょう。そうかそうでないかやってみれば分かるでしょう。
もし、そうなら、実際にutf-8で渡ってるのでしょう。実際どういうヘッダが来たのか確かめたのですか?
IE(IE8)でWebサイトからファイルをダウンロードする際にファイル名の日本語が文字化けします。
全てのクライアントで文字化けするのではなく、特定のクライアントで文字化けが発生するので、
- 編集済み ウィンドウズスクリプトプログラマ 2014年2月21日 14:18
-
本来のIEの仕様としては、charset→Sjisで文字化けすることなく処理可能なはず
以下に書かれている内容なのですね。
http://support.microsoft.com/kb/436616/ja
サーバ側は修正せず、クライアント側IEの設定変更等で解消したいです。
上記URLのサンプルコードはSJISで返却するように指示があり、
多くのブラウザで動作するそうです。
差分を確認すると何かヒントがあるかもしれません。 -
いずれにせよ、インターネットでファイル名に日本語を使うのはまだ早いのでは。あと10年くらいかかるのでは。
だって、未だに
Internet Explorer では、ログイン時のユーザー名につきまして、2 バイト文字を正式にサ ポートしておりません。
てな状況ですから。
- 編集済み ウィンドウズスクリプトプログラマ 2014年2月21日 17:20
-
> 補足ですが、上記サポート技術情報でShift-JISで返却するサンプルコードが記載されている意図は、
> 以下のブログにありました。
> http://blogs.msdn.com/b/d99/archive/2012/02/09/10265861.aspxそのブログの記述の中の "「IE ダメ ワロスwww」 みたいなコメントが付けられていたのが、いつもとても気がかりでした。" というところが個人的に面白かったです。
でも filename=日本語.zip のようにすると(実際の応答ヘッダの中で "日本語" の部分は UTF-8 で、HexView で見ると、e6 97 a5 e6 9c ac e8 aa 9e)、IE, Firefox, Chrome, Safari, Opera の中では IE だけがダメというのは事実です。
また、
> 「実際問題、現実的に動く ASP.NET サーバーサイドコードは何なんだ!?」 という視点も盛り
> 込みたいと思い、RFC5987/2231 には沿っていないのですがベタ Shift-JIS でファイルをダウン
> ロードさせるサンプルコードも追加してみました。とのことですが、プロキシで化ける可能性があるということで、「現実的に動く」とはいえないような気がします。
では、
Response.AppendHeader("Content-Disposition", "Attachment; filename*=utf-8''" + Server.UrlEncode(FileName));
なら問題ないかというと、自分が試した限りですが、IE9, Firefox 26.0, Chrome 33.0.1750.117 m, Opera 12.16 は OK でしたが、Safari 5.1.7 は対応していないようです。
なので、「実際問題、現実的に動く ASP.NET サーバーサイドコードは何なんだ!?」というと、以下のようなコードになるのではないかと思います。
string fileName = "日本語.zip"; if (Request.Browser.Browser.ToUpper().IndexOf("IE") >= 0) { fileName = Server.UrlEncode(fileName); } Response.AppendHeader("Content-Disposition", "attachment;filename=" + fileName);
UrlEncode するだけで 100% 文字化けを防ぐことはできないようですが、他に「現実的」な解決策が思い浮かびません。他にもっとよい解決策があれば教えていただけると幸いです。
-
佐祐理さん、(´・ω・`)さん>
レスを有難うございます。
> • Content-Disposition:attachment; としてファイル名は含めない
> • URL末尾にファイル名を含めるは、確かに文字化けなしでうまく行きますが、「URL末尾にファイル名を含める」が自分としては問題です。
> 未調査ですがRFCにあるようにfilenameを2つ並べる手も加えて、IndexOf("IE")を
> 消せないでしょうか?それは 5. Examples に書いてある以下のようにするということですか?
Content-Disposition:attachment; filename="EURO rates"; filename*=utf-8''%e2%82%ac%20rates
そうだとすると filename="EURO rates"; の方が問題です。例えば以下のコードでは、fileName が UTF-8 のままでエンコードしてないので IE8 は文字化けします。
string fileName = "日本語.zip"; string encodedFileName = Server.UrlEncode(fileName); Response.AppendHeader("Content-Disposition", "attachment;" + "filename=" + fileName + ";filename*=utf-8''" + encodedFileName);
ちなみに、IE9, Firefox, Chrome, Opera, Safari は OK でした。先のレスで書きましたが、"filename=" + fileName + がない場合は Safari がダメです。
というわけで、結局、先のレスのサンプルコードで書いた、
if (Request.Browser.Browser.ToUpper().IndexOf("IE") >= 0) { fileName = Server.UrlEncode(fileName); }
は消せないです。
(注)化けてしまうので Content-Disposition:attachment; の : は全角にしています。
- 編集済み SurferOnWww 2014年2月23日 5:13 文字化け訂正
-
結局、一番問題なさそうなのは以下のような設定ではないかと思います。
string fileName = "日本語.zip"; string encodedFileName = Server.UrlEncode(fileName); if (Request.Browser.Browser.ToUpper().IndexOf("IE") >= 0) { Response.AppendHeader("Content-Disposition", "attachment;" + "filename=" + encodedFileName + ";filename*=utf-8''" + encodedFileName); } else { Response.AppendHeader("Content-Disposition", "attachment;" + "filename=" + fileName + ";filename*=utf-8''" + encodedFileName); }
IE8, IE9, Firefox 27.0.1, Chrome 33.0.1750.117, Safari 5.1.7, Opera 12.16 で "日本語" が正しく表示されることを確認しました。
まぁ、その前に、ウィンドウズスクリプトプログラマさんが言われるように、ダウンロードするファイル名に日本語を使うのは 10 年早いのかもしれませんが。とにかく、質問者さんの解決策「ヘッダに Shift_JIS コードを含める」というのは、予期せぬ副作用が多そうなので止めた方がよさそうです。
- 編集済み SurferOnWww 2014年2月23日 6:22 一部追加
-
いえいえ、
Request.Browser.Browser.ToUpper().IndexOf("IE") >= 0
これ辺を知らないので、聞いてます。
の
if (strstr($ua, 'MSIE') && !strstr($ua, 'Opera')) {
はie11で誤判定するようなので、もしかして同じじゃないかと。
PHPで生成したファイルを日本語ファイル名でダウンロードさせます。
はie11で文字化けします。
それとはどう違うのか確認したくて聞いてます。
ie11の場合は、どっちを通っても、
";filename*=utf-8''" + encodedFileName);
でOKになるということでしょうか。
また、そこには、
// $filename = '=?UTF-8?B?' . base64_encode($filename) . '?=';
で渡るように書いてあるのですが、開発者モードでキャプチャしても、デコードしてあるようで、実際どう渡って来たのか見えないのです。たぶんキャッシュのDBを見れば、分かるでしょうが、使用中DBは見れないので厄介なんです。ちなみに、その例では、ie11で開発者モードでヘッダは正常。保存で文字化け。user agent ie10で、開発者モードでヘッダは文字化け。保存は正常。
キャッシュDBを見ると、前者はutf-8、後者はshift_jisでした。Bエンコーディングじゃない。
つまり、そこの
header('Content-Dis; filename="' . $filename . '"');う
はutf-8ってことですね。
"filename=" + fileName +
も、
ファイルをダウンロードする ASP.NET ページで日本語ファイル名が文字化けする
から察するに、utf-8ってことですね。
- 編集済み ウィンドウズスクリプトプログラマ 2014年2月24日 10:42
-
一般に、古いieで、url encodeでなく、shift_jisにする理由は、url encodeにすると、ファイル名長制限で、ファイル名が切り詰められるからのようです。
なので、古いieは、ファイル名長によってshift_jisにしたほうがよさそう。
ちょっと古いですがDownloads and International Filenamesでは、
- Content-Disposition: attachment;としてファイル名は含めない
- URL末尾にファイル名を含める
という方法が提案されていますね。
これは、ファイル名長制限に引っ掛かりそう。
やっぱり、IF判定が必要なブラウザが一般に使われなくなるまでは、日本語文字は使わないほうがよいと思う。
ie8で、なんて論外。つまり、少なくとも2020年1月14日までは論外かも。
日本語ファイル みたいにサンプルサイトがあると、確認しやすいんですけど。だれか作って。
- 編集済み ウィンドウズスクリプトプログラマ 2014年3月7日 7:45
-
IE10, IE11 は持ってないので IE8, IE9, Firefox 27.0.1, Chrome 33.0.1750.117, Safari 5.1.7, Opera 12.16 でしか試してないです。
IE9 ではどちらを通っても文字化けの問題はなかったので、たぶん IE10, IE11 もどちらを通っても問題ないと想像していますが、どなたか確認いただければ幸いです。
ちなみに、ネットの情報によると Request.Browser.Browser は IE11 では "InternetExplorer" になるそうです(IE10 以前は "IE")。Microsoft の公式文書には変更になったという記述は見つけられなかったので、これも定かではないですが。
HttpCapabilitiesBase.Browser プロパティ
http://msdn.microsoft.com/ja-jp/library/system.web.configuration.httpcapabilitiesbase.browser(v=vs.110).aspx -
> ieでshift_jisにする理由は、url encodeすると、ファイル名長制限で、ファイル名が
> 切り詰められるからのようです。佐祐理さんが紹介されたブログの記事には以下のような記述があります。
"Early versions of Internet Explorer worked around this limitation by assuming that any non-ASCII characters within HTTP headers were encoded using the local system's Windows codepage"
Shift_JIS にすることを推奨しているわけではなくて、上記のような仕様になっているので Shift_JIS にすると文字化けが回避できると言っているだけのような気がします。
-
日本語ファイル みたいにサンプルサイトがあると、確認しやすいんですけど。だれか作って。
こちらにもありますね。
あと、urlエンコードで長いケースがあればよいのだけれど。
一応、ie6とie8は、
Internet Explorer 6 でのダウンロード時、既定のファイル名として日本語使うと16文字にカットされてしまう : @jsakamoto
ie7は、
なので、古いieだけ判定すればよさそう。
ie6はもう考えなくてよさそうだけど、ie7は、2017年4月11日まで。ie8は202文字なら考えなくてもよさそう。
- 編集済み ウィンドウズスクリプトプログラマ 2014年3月6日 7:00