IEでファイルダウンロード時の文字化け

IEで長いファイル名のファイルをダウンロードするとファイル名が文字化けする

ダウンロード処理をする時にサーバ側でファイル名をURLエンコードして、
HttpHeaderのContent-Dispositionにfilenameを指定していたのだが、
ファイルによって文字化けが発生したりしなかったり。


例えば
  『あいうえおかきくけこさしすせそたちab.txt』
こんな感じのファイルをダウンロードした場合、
ダウンロードダイアログが開いたときにファイル名が
  『%81%82いうえおかきくけこさしすせそたちab.txt』
となって文字化けを起こした。

原因

調べてみるとこんなページを発見。要約すると
Windowsのファイルパスの長さはフルパスで256byte未満でないとだめで、
ファイルをダウンロード時に一時フォルダとして、
C:\Documents and Settings\<ユーザー名>\Local Settings\Temporary Internet Files\Content.IE5\<半角8文字のランダムな文字列>
以下にファイルを保存する。


その為、ダウンロードするファイル名が長いと、上記のパスと合わせて256byteを超えてしまうので、
サイズ制限内で収まるようにファイル名を切り詰めるということだ。
つまり上記のパスの時点でユーザ名を除いて87byteあるので、残り169byteがファイル名の限界となる。


169byteあればファイル名としては十分に感じられるが、
この一時領域にはURLエンコードされたままのファイル名で保存する為、
マルチバイト文字を使った場合、思いのほか短くなる。


先のファイル名だとURLエンコードをすると
『%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A%E3%81%8B%E3%81%8D%E3%81%8F%E3%81%91%E3%81%93%E3%81%95%E3%81%97%E3%81%99%E3%81%9B%E3%81%9D%E3%81%9F%E3%81%A1ab.txt』
となるので158byteあることになる。
これにWindowsのログインユーザ名を合わせると256byteを超えるパスに保存す事になるので、ファイル名が切り詰められて文字化けを起こしたように見えたというわけ。


更に同じファイルを2回ダウンロードすると一時ファイルとして保存するファイル名は
自動で『ファイル名.txt[1]』というように添え字が振られるので更に3byte短くなる。


とはいえ20文字程度のマルチバイト文字のファイルなんてざらにあるわけで、
何らかの方法を考える必要がある。

対策

考えられる対策として
クライアント側で

  • IEを使わない
  • IEのTemporaryフォルダをC:\tmpなど短いパスに変更してもらう
  • ログインユーザ名を短くする
  • マルチバイト名ファイルを扱わない

など。


パスを変えたり、ユーザ名を短くして数バイト縮めたところで、
URLエンコードをすると1文字あたりが6byteあるのでほとんど効果はない。
おススメはやっぱり、1番上のIEを使わないかな。


あとサーバ側を直せるなら、URLエンコードをせずにShift_JISでファイル名を送るという方法もある。
この場合、2バイトコードの下位バイトが「5C」「7C」になる文字だけはURLエンコードをしないといけないようだ。
開発者の談話室



しかし勝手に切り詰めるってすごい仕様だな〜。
IEには本当に困ったもんだ。