2010-04-05 40 views
5

當我試圖下載其名字有來自像中國日本等......非ASCII語言字符的文件...下載文件名稱是亂碼。如何糾正它。而來自非英語語言的下載文件名沒有得到下載的文件顯示正確

我試圖把字符集= UTF-8的Content-type頭財產,但沒有成功。請幫忙。下面的代碼。

標題(「緩存控制: 」); //留空,以避免錯誤IE

標題(「 附註: 」); //留空,以避免錯誤IE

標題(「 內容-type:application/octet-stream「);

標題( 「內容處置:附件;文件名= \」 「$ INSTANCE_NAME 」\「」);

標題( 「內容長度:」(字符串)(文件大小($ fileString)));

sleep(1);

fpassthru($ fdl);

+1

請添加一些基本信息。 '$ fileString'從哪裏來?它是什麼編碼? – 2010-04-05 12:36:14

+0

變量從數據庫中挑選並使用。 instance_name和filestring – pks83 2010-04-05 12:46:40

回答

9

不幸的是,目前還沒有一種適用於所有瀏覽器的解決方案。 至少有三個「更明顯」的方法來解決這個問題。

a)Content-type: application/octet-stream; charset=utf-8 + filename=<utf8 byte sequence>
例如, filename=Москва.txt
這是違反標準,但Firefox正確顯示名稱。 IE沒有。

B)Content-type: application/octet-stream; charset=utf-8 + filename=<urlencode(utf8 byte sequence)>
例如filename=%D0%9C%D0%BE%D1%81%D0%BA%D0%B2%D0%B0.txt
這適用於IE瀏覽器,但不適用於Firefox。

c)根據在rfc 2231
指定提供該名稱e.g filename*=UTF-8''%D0%9C%D0%BE%D1%81%D0%BA%D0%B2%D0%B0.txt
再次Firefox支持這一點,即,不。

一個更全面的比較看http://greenbytes.de/tech/tc2231/


編輯:當我說,沒有單一的解決方案,通過我的意思頭(「...」)。但是有一些工作要做。
當沒有可用的文件名時= xyz標頭瀏覽器使用url的路徑部分的基本名稱。即對於<a href="test.php/lala.txt"> Firefox和IE都建議使用lalala.txt作爲文件名。
可以追加額外的路徑組件後,實際路徑到您的PHP腳本(當使用Apache的httpd見http://httpd.apache.org/docs/2.1/mod/core.html#acceptpathinfo)。
例如如果您的文檔根目錄中有一個文件test.php,並將其請求爲http://localhost/test.php/x/y/z,則變量$_SERVER['PATH_INFO']將包含/x/y/z。現在
,如果你把一個鏈接像

<a 
    href="/test.php/download/moskwa/&#x41c;&#x43e;&#x441;&#x43a;&#x432;&#x430;" 
> 
    &#x41c;&#x43e;&#x441;&#x43a;&#x432;&#x430; 
</a> 

您的文檔中,你可以獲取download/moskwa/...部分並開始文件的下載。不發送任何文件名= ...信息Firefox和IE均提示「正確」的名稱。
你甚至可以將它與根據rfc 2231發送名稱相結合。這就是爲什麼我也把moskwa放入鏈接。這將是腳本用來查找它應該發送的文件的id。 IE忽略filename*=...信息並仍然使用url的基本名稱部分來建議名稱。這意味着對於Firefox(和任何其他支持RFC 2231的客戶端),id之後的部分沒有意義*,但對於IE(和其他不支持rfc 2231的客戶端),它將用於名稱建議。
自足例如:

<?php // test.php 
$files = array(
    'moskwa'=>array(
    'htmlentities'=>'&#x41c;&#x43e;&#x441;&#x43a;&#x432;&#x430;', 
    'content'=>'55° 45′ N, 37° 37′ O' 
), 
    'athen'=>array(
    'htmlentities'=>'&#x391;&#x3b8;&#x3ae;&#x3bd;&#x3b1;', 
    'content'=>'37° 59′ N, 23° 44′ O' 
) 
); 


$fileid = null; 
if (isset($_SERVER['PATH_INFO']) && preg_match('!^/download/([^/]+)!', $_SERVER['PATH_INFO'], $m)) { 
    $fileid = $m[1]; 
} 

if (is_null($fileid)) { 
    foreach($files as $fileid=>$bar) { 
    printf(
     '<a href="./test.php/download/%s/%s.txt">%s</a><br />', 
     $fileid, $bar['htmlentities'], $bar['htmlentities'] 
    ); 
    } 
} 
else if (!isset($files[$fileid])) { 
    echo 'no such file'; 
} 
else { 
    $f = $files[$fileid]; 
    $utf8name = mb_convert_encoding($f['htmlentities'], 'utf-8', 'HTML-ENTITIES'); 
    $utf8name = urlencode($utf8name); 

    header("Content-type: text/plain"); 
    header("Content-Disposition: attachment; filename*=UTF-8''$utf8name.txt"); 
    header("Content-length: " . strlen($f['content'])); 
    echo $f['content']; 
} 

*)這是一個有點像在這裏堆棧溢出。的鏈接,這個問題被顯示爲

http://stackoverflow.com/questions/2578349/while-downloading-filenames-from-non-english-languages-are-not-getting-displayed 

,但它也可以與

http://stackoverflow.com/questions/2578349/mary-had-a-little-lamb 

的重要組成部分,是id 2578349

+0

+1是我見過的最好的答案。感謝您的鏈接。這進入我的最愛箱子。 – 2010-04-05 13:45:24

+0

感謝您提供詳細的解釋,幫助我們更深入地瞭解問題。謝謝 – pks83 2010-04-06 05:32:02

+0

您好VolkerK, 關於如何處理Safari的任何輸入? – pks83 2010-04-07 12:49:39

0

我想如果你嘗試添加其他字符集將修復你的proplem。

如果proplem還是我想你需要從XP CD語言文件安裝到您的系統,因爲如果系統無法找到合適的字符,它會增加奇怪的。

我有這樣的proplem與阿拉伯語,但我發現我沒有所有的語言文件複製到我的系統。

希望這會幫助你。