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

  • 質問

  • IE(IE8)でWebサイトからファイルをダウンロードする際にファイル名の日本語が文字化けします。

    Webサイトからファイルをダウンロードする際には、以下のHTTPヘッダがWebサーバから送信されますが、

    Content-Dis; filename="ファイル名"

    この"ファイル名"はSjisでエンコードされた状態でクライアントに送信されています。

    IEはこの"ファイル名"をSjisでエンコードしてあるものとして扱う仕様であるらしいので、問題なくダウンロードできるはずです。
    全てのクライアントで文字化けするのではなく、特定のクライアントで文字化けが発生するので、

    どこかの設定が原因ではないかと考えているのですが、

    お教えいただけると非常に助かります。

    なお、Webサーバからの以下のHTTPヘッダで

    Content-Dis; filename="ファイル名"

    ファイル名をSjisではなくURLエンコードとした場合には文字化けすることなくファイルをダウンロードできます。

    Content-Dispositionのファイル名がSjisの場合には文字化けが発生し、URLエンコードの場合には文字化けしません。

    本来のIEの仕様と異なる動作のようですが、原因がわかりますでしょうか。

    何卒よろしくお願い致します。

    2014年2月18日 9:46

回答

  • > 以下に書かれている内容なのですね。
    > http://support.microsoft.com/kb/436616/ja

    ちょっと試してみましたが、Fiddler2 を使うと文字化け、使わないと問題なく "日本語" と表示されました。

    質問さんの一番最初の質問によると・・・

    > 全てのクライアントで文字化けするのではなく、特定のクライアントで文字化けが発生するので、

    ・・・とのことですが、プロキシの有無が影響しているのかもしれません。

    • 回答としてマーク k-k2 2014年3月10日 4:57
    2014年2月21日 15:02

すべての返信

  • まず、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エンコーディングが無難な解ではないでしょうか。


    • 編集済み 佐祐理 2014年2月18日 13:10 誤字訂正
    • 回答の候補に設定 佐祐理 2014年3月10日 5:01
    2014年2月18日 13:09
  • > Content-Dis; filename="ファイル名"

    というのは確かなんですか?

    Content-Disposition: attachment; filename=... の間違いですか?

    ・・・と書いたんですが、全部の文字を半角で書くと、勝手に変えられてしまいますね(上記は : が全角です)。であれば、失礼しました。




    • 編集済み SurferOnWww 2014年2月18日 16:25 一部訂正&追記
    2014年2月18日 16:13
  • 一口に文字化けと言われても、いろいろですから。どういう文字化けか説明してもらわないと分かりません。

    utf-8をshift_jisで見た、とか。

    同じie8で、となると、キャッシュの不具合でしょう。

    2014年2月19日 8:03
  • 皆様、ご返答誠にありがとうございます。

    charsetとencodingについて詳細を記載します。

    ・文字化けするパターン:charset→Sjis、encoding→なし

    ・文字化けしないパターン:charset→Utf8、encoding→URLエンコーディング

    です。

    文字化けの仕方としては、Utf8の文字をSjisで開く際の化け方に似ています。

    本来のIEの仕様としては、charset→Sjisで文字化けすることなく処理可能なはずであることと、

    一部のクライアントのみで文字化けが発生していることから、クライアント側の設定等で解消したいです。

    つまり、サーバ側で「charset→Utf8、encoding→URLエンコーディング」とすることでも回避は可能なのですが、

    サーバ側は修正せず、クライアント側IEの設定変更等で解消したいです。

    何卒、アドバイスの程よろしくお願い致します。

    2014年2月20日 8:57
  • 文字化けの仕方としては、Utf8の文字をSjisで開く際の化け方に似ています。

    似ていますって何でしょう。そうかそうでないかやってみれば分かるでしょう。

    もし、そうなら、実際にutf-8で渡ってるのでしょう。実際どういうヘッダが来たのか確かめたのですか?


    IE(IE8)でWebサイトからファイルをダウンロードする際にファイル名の日本語が文字化けします。

    全てのクライアントで文字化けするのではなく、特定のクライアントで文字化けが発生するので、

    文字化けするのはie11では。サーバがuser agentを見てieでないと思ってutf-8で返してるのでは。
    2014年2月20日 12:28
  • 本来のIEの仕様としては、charset→Sjisで文字化けすることなく処理可能なはず
    以下に書かれている内容なのですね。
    http://support.microsoft.com/kb/436616/ja
     
    サーバ側は修正せず、クライアント側IEの設定変更等で解消したいです。

    上記URLのサンプルコードはSJISで返却するように指示があり、
    多くのブラウザで動作するそうです。
    差分を確認すると何かヒントがあるかもしれません。

    2014年2月21日 13:45
  • > 以下に書かれている内容なのですね。
    > http://support.microsoft.com/kb/436616/ja

    ちょっと試してみましたが、Fiddler2 を使うと文字化け、使わないと問題なく "日本語" と表示されました。

    質問さんの一番最初の質問によると・・・

    > 全てのクライアントで文字化けするのではなく、特定のクライアントで文字化けが発生するので、

    ・・・とのことですが、プロキシの有無が影響しているのかもしれません。

    • 回答としてマーク k-k2 2014年3月10日 4:57
    2014年2月21日 15:02
  • いずれにせよ、インターネットでファイル名に日本語を使うのはまだ早いのでは。あと10年くらいかかるのでは。

    だって、未だに

    Internet Explorer では、ログイン時のユーザー名につきまして、2 バイト文字を正式にサ ポートしておりません。
    てな状況ですから。

    2014年2月21日 17:13
  • 補足ですが、上記サポート技術情報でShift-JISで返却するサンプルコードが記載されている意図は、
    以下のブログにありました。
    http://blogs.msdn.com/b/d99/archive/2012/02/09/10265861.aspx
     
    Proxyを使用されている場合、HTTPヘッダの編集操作がありますので、ヘッダ中に非asciiが存在すると文字化けの確率は格段に上がります。
    また、アドオンやウィルスチェッカなどを無効にする方法も有効かもしれません。

    2014年2月22日 3:29
  • だからこう書いたんですけどね。

    SJISでは中継するProxyサーバーが文字化けを引き起こす可能性もありますから(だからこそエンコーディングに関する仕様が必要だった)
    2014年2月22日 4:38
  • > 補足ですが、上記サポート技術情報で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% 文字化けを防ぐことはできないようですが、他に「現実的」な解決策が思い浮かびません。他にもっとよい解決策があれば教えていただけると幸いです。

    2014年2月22日 6:42
  • 他に「現実的」な解決策が思い浮かびません。他にもっとよい解決策があれば教えていただけると幸いです。

    ちょっと古いですがDownloads and International Filenamesでは、

    • Content-Disposition: attachment;としてファイル名は含めない
    • URL末尾にファイル名を含める

    という方法が提案されていますね。


    • 編集済み 佐祐理 2014年2月22日 9:43 いい加減にフォーラムの文字化けバグを直してください
    2014年2月22日 9:42
  • 未調査ですがRFCにあるようにfilenameを2つ並べる手も加えて、IndexOf("IE")を消せないでしょうか?

    佐祐理が提示されたサイトでは、当時はうまくいかなかったようですが。

    2014年2月22日 18:48
  • 佐祐理さん、(´・ω・`)さん>

    レスを有難うございます。


    > • 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 文字化け訂正
    2014年2月23日 5:10
  • 結局、一番問題なさそうなのは以下のような設定ではないかと思います。

     
    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 一部追加
    2014年2月23日 6:16
  • それってie11のときはどっちを通るんでしょう?

    また

     "filename=" + fileName +
    の場合は、実際にはどういうヘッダが渡るんでしょう?

    2014年2月23日 10:27
  • > それってie11のときはどっちを通るんでしょう?

    知ってて聞いてるみたいですが、であればきちんと言ったらどうですか?

    知って言ってるのなら、すごく陰険な感じというか敵意すら感じますよ。

    2014年2月23日 10:47
  • いえいえ、

    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月23日 12:50
  • 一般に、古いieで、url encodeでなく、shift_jisにする理由は、url encodeにすると、ファイル名長制限で、ファイル名が切り詰められるからのようです。
    なので、古いieは、ファイル名長によってshift_jisにしたほうがよさそう。

    ちょっと古いですがDownloads and International Filenamesでは、

    • Content-Disposition: attachment;としてファイル名は含めない
    • URL末尾にファイル名を含める

    という方法が提案されていますね。

    これは、ファイル名長制限に引っ掛かりそう。

    やっぱり、IF判定が必要なブラウザが一般に使われなくなるまでは、日本語文字は使わないほうがよいと思う。

    ie8で、なんて論外。つまり、少なくとも2020年1月14日までは論外かも。

    日本語ファイル みたいにサンプルサイトがあると、確認しやすいんですけど。だれか作って。

    2014年2月24日 8:18
  • 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

    2014年2月24日 9:18
  • > 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 にすると文字化けが回避できると言っているだけのような気がします。

    2014年2月24日 9:30
  • 日本語ファイル みたいにサンプルサイトがあると、確認しやすいんですけど。だれか作って。

    こちらにもありますね。

    日本語でファイル保存

    あと、urlエンコードで長いケースがあればよいのだけれど。

    一応、ie6とie8は、

    Internet Explorer 6 でのダウンロード時、既定のファイル名として日本語使うと16文字にカットされてしまう : @jsakamoto 

    ie7は、

    BK通信 - ブラウザのバッドノウハウ コンテンツ編

    なので、古いieだけ判定すればよさそう。

    ie6はもう考えなくてよさそうだけど、ie7は、2017年4月11日まで。ie8は202文字なら考えなくてもよさそう。

    2014年3月6日 6:29
  • 質問者です。

    みなさん、誠にありがとうございます。

    頂いたアドバイスよりプロキシが関係していそうなので、確認しようと思います。

    誠にすみませんが、もう少々本スレッドをOpenさせてください。

    2014年3月7日 8:40
  • プロキシサーバの影響と判断しました。

    ご対応誠にありがとうございました。

    2014年3月10日 4:56