まだよくわかっていないことが多いので,お気づきの点がありましたらご教示ください。
[2006-05-08] WindowsのIEで化けていた(^^;)ので直しました。
[2007-03-14] IE5/6はUTF-8をURLエンコードした名前でもOKだそうです(Thanks: 白水さん)。
日本語ファイル名の扱い方はブラウザによって異なり,たいへん厄介です。
まず,ファイル名はURLのパスとして与えることができます:
<a href="fakefile.php/日本語ファイル名.txt">クリックしてね</a>
この場合,ブラウザは「日本語ファイル名.txt」というファイルを見ているつもりになりますが,サーバ側では fakefile.php を実行し,/日本語ファイル名.txt
はその実行の際に環境変数 PATH_INFO
として渡されるだけです。
また,ファイル名はHTTPヘッダによっても与えることができます:
Content-Type: text/plain; charset=UTF-8 Content-Disposition: attachment; filename="日本語ファイル名.txt"
ブラウザはこのどちらのファイル名を見るかという問題と,それらのファイル名をどういうエンコーディングにすればいいかという問題があります。
まず考えられるのはUTF-8で,今後はこれが主流になっていくと思いますが,IEはファイル名についてはまだShift JISでないと文字化けするようです。
さらに,URLエンコード(%に続く2桁の16進表記)するか,RFC 2047流にMIMEエンコード(=?ISO-2022-JP?B?....?=
のような形式)するか,それとも生のままにするか,という問題があります。
また,RFC 2231によれば filename*=iso-2022-jp'ja'URLエンコードされたファイル名
のように書くのが正しそうです。
また,少なくともURLに含ませる場合は,特殊文字の扱いには要注意です。
例えば 日本語#ファイル.txt
と書くと 日本語.txt
のように扱われてしまうので,日本語%23ファイル.txt
のようにURLエンコードしなければならないようです。
PHPで生成したファイルを日本語ファイル名でダウンロードさせます。
飛び先の fakefile.php は次のようになっています:
<?php if (isset($_SERVER['PATH_INFO'])) { $filename = substr($_SERVER['PATH_INFO'], 1); } else { $filename = "不明.txt"; } $ext = substr($filename, -4); if ($ext == '.txt') $type = 'text/plain'; else $type = 'application/octet-stream'; $ua = $_SERVER['HTTP_USER_AGENT']; if (strstr($ua, 'MSIE') && !strstr($ua, 'Opera')) { // IE(オペラの仮装でない)はSJISにしないと化ける $filename = mb_convert_encoding($filename, "SJIS", "UTF-8"); // $filename = urlencode($filename); $content = 'あなたのブラウザはIEですね。'; } elseif (strstr($ua, "Safari")) { // どうやっても化けるのでContent-Dispositionでなく // URLの最後の部分(PATH_INFO)でファイル名を指定 $filename = ""; $content = 'あなたのブラウザはSafariですね。'; } else { // $filename = '=?UTF-8?B?' . base64_encode($filename) . '?='; $content = 'あなたのブラウザはIEでもSafariでもありませんね。'; } header('Content-Type: ' . $type); header('Content-Disposition: attachment; filename="' . $filename . '"'); echo $content, "\n"; ?>
Last modified: