您在這裡

下載時的中文檔名

hom's 的頭像
hom 在 2008-10-13 (週一) 15:19 發表

最近研究了下載中文檔名的部份
拿最近自己寫的 upload_ch 來做測試

一開始是用 windows XP + firefox 3 對 windows XP + xampp 的 server 做上傳/下載 中文檔名的測試 這部份是 ok

接著是用 windows XP + firefox 3/IE 對區網內的 linux + xampp 的 server 做上傳/下載 中文檔名的測試
這部份讓我覺得怪怪的
因為我在程式內還沒使用 iconv 將 UTF-8 轉換成 big5
但是用 firefox 上傳/下載中文檔名都是正常的
不過 IE 則是跳出無法下載的訊息後就被中斷了

然後是用 windows XP + firefox 3/IE 對外部機房內的 linux + xampp 的 server 做上傳/下載 中文檔名的測試
上傳的部份 資料庫內會正確記錄上傳時的中文檔名
下載的部份就出現了問題
點了下載連結後 跳出的下載視窗 檔名內含有中文的部份 都會變成底線
即使加上 mb_convert_encoding() 或 iconv() 也都是一樣的情況
後來是參考了 http://twpug.net/modules/newbb/viewtopic.php?post_id=12052 附件的程式
IE要 urlencode() 對檔名編碼,FireFox 用 mb_encode_mimeheader() 的QP對檔名編碼
目前測試過 firefox 和 IE 都可以正確下載中文檔名

不過途中還發現一個問題
file_transfer($file->filepath, $header); 是 drupal 提供用來輸出檔案下載 header 的 function
但是用 file_transfer() 輸出之後 檔名內雖然可以正確顯示中文 但是卻發現檔名後段被截斷而消失了
然而自己使用 header('Content-Disposition: attachment; filename="'.$filename.'"'); 輸出卻是完整的檔名

底下附上經過這次測試修改的 upload_ch
順便修正了 .install 檔內的錯誤 以及加上自訂下載路徑開頭的功能

附加檔案大小
Package icon upload_ch-5.x-1.0.zip4.1 KB

您好:

我有安裝upload_ch這各模組但遇到問題,所以想請教一下,

我安裝了這各模組後,用管理員帳號新增中文檔名上去沒問題,但用一般帳號就出現錯誤 (用同一個中文檔案以兩個帳號進行測試)

管理 -> 使用者管理 -> 權限控制
authenticated user 裡的 upload 模組 (上傳檔案) (檢視上傳檔案) 權限有打開

是否還有哪邊需要設定? 錯誤情形如附檔~~~

P.S:upload_ch有6.X版本的嗎? (我找不到...所以就安裝5.x版本~~~)

可以提供一下安裝的環境嗎

  1. windows/linux ?
  2. php 的版本?
  3. 是否有安裝其他跟檔案有關的模組?
  4. 上傳檔案的檔名?如果可以的話,直接提供檔案讓我做測試會更好

這個模組是我之前測試的時候順手開發的產物
我已經盡量在所有手邊可以湊到的環境下做測試
不過可能還是會有缺漏
所以麻煩請你提供一下相關的資訊,這樣 debug 會比較容易

然後,我還沒有時間研究 6.x 模組的寫法
所以目前還沒辦法製作 6.x 的版本

前輩你好:
1.系統是windows xp (Drupal 5.07中文包 然後 Update 到5.16 )
2.安裝appserv 2.5.10 (Apache 2.2.8、PHP 5.2.6、MySQL 5.0.51b)
3.目前安裝的模組共有FCKeditor、CCK、Views、date、IMCE、Upload CH

我都沒想到可能是php版本的問題...順便說一下在上述環境下遇到的問題主要有兩個
1.一般帳號無法上傳中文檔名 (內、外網 IE6)
2.用管理員帳號於外網測試中文檔名時,上傳過程常常會卡住,導致檔案無法上傳成功 (就是選好欲上傳檔案 -> 按下上傳 -> 然後就一直停留在上傳中的動畫...)
假如作者用其他版本測試都沒這些問題..看來我該改用其他版本了 = =

看起來主要是因為 drupal 版本更新的關係造成模組運作錯誤
應該不是因為 windows 環境的問題

5.16 在檔案處理的部份有調整過
_upload_prepare 函式內會用 upload_munge_filename 函式針對檔名做處理
強迫檔名一定是 [檔名].[附檔名] 的格式
所以原本被我改成索引數字的檔名就會變成多了一個 . 號
造成檢查允許上傳的檔案類型時產生錯誤
而 admin 則是不會執行檢查,所以可以上傳檔案

針對這點修改之後
國際青年旅舍卡申請書.doc 會先變成 [auto_id].doc
讓檢查檔案類型的時候可以取得附檔名
然後再儲存之前再將檔案名稱 [auto_id].doc 改成 [auto_id]
讓檔案的紀錄和中文名稱的紀錄有可以對應的 key

放上修改過後的模組檔案再試試看吧,不好意思拖了這麼久

前輩你好...我昨天發現了一個問題...
跟之前一樣,用管理員帳號就沒問題,是一般帳號才會發生的問題
目前都可以上傳中文檔名,但使用一般帳號時
1.上傳 "檔案1" 沒問題
2.上傳 "檔案2" 時,"檔案1" 的檔案名稱會被修改掉 @@

前輩:感謝你啦~~~
剛剛掛上去測試過了,成功~~~

還有另外一個小問題,就是檔案名稱中若遇到 " " 半形空白字元下載時會變成 "+"
這部份不管是admin還是user帳號來上傳,結果都一樣

例如:上傳檔案 新增Microsoft Word 文件1.doc
完成後在網頁內容看是正常的
但下載時檔名就會變成:新增Microsoft+Word+文件1.doc

原本 for IE 的下載會將中文檔名用 urlencode() 編碼
空白的部份會被轉換成 + 號
IE7 會正常的轉換回來
不過 IE 6 不會
這部份改成用 rawurlencode() 來編碼,將空白轉換成 %20,這樣 IE 6 下載的檔名也正常了

firefox 的部份保持用 mb_encode_mimeheader() 函式編碼

我順便測試了 opera,safari,Chrome
opera 最神奇,完全不用編碼也不用修正,直接輸出中文檔名就可以正常顯示
Chrome 則需要將檔名編碼,不過不管用 rawurlencode() 還是 mb_encode_mimeheader() 編碼都可以正常顯示

safari 最慘,google 的結果中文檔名目前無解,除非瀏覽器端自行安裝修正的插件。
包含 英數底線減號.空白之外字元的檔名,強迫修正成 File[fid][auto] 的格式,避免中文檔名,這是我目前想到的作法

剛剛掛上去,使用IE 6下載正常了,這兩天又麻煩前輩了,晚輩只能說感激不盡!!
P.S:下載檔名跟瀏覽器有關,對我來說...這解答挺神奇的~~~
我們全公司都只能用IE,最多就IE 6跟IE 7,還不能安裝其他瀏覽器說 = =

不是在潑冷水,這問題當初我有研究過一陣子。

最後的結果是,我認為在 Windows 當伺服器的前提下,最好的方式還是把檔名作序列化編碼,把對應的檔名資料寫進資料庫,要下載用前端控制程式去處理下載問題。
如果你的應用是讓PHP作串流傳輸的話,不允許中文檔名是必要的事情。(使用 MS 的 Media Server 是另當別論)

目前版本伺服器端存放的上傳檔案是用 auto ID 作為檔名
並不會是中文
所以是 linux 還是 windows 其實沒有差別
原始的中文檔名是記錄在資料庫內
當下載的時候才會依據檔案ID取得原始的中文檔名
透過 header 設定檔案儲存時的預設檔名(瀏覽器解讀會有差異的部份)

前輩...中文檔名外這部分靠前輩的模組圓滿解決,但我發現一個怪現象
我設定了單檔上傳最大值80mb,總容量也是設定80mb,經過測試可以順利上傳附加檔案
但除了登入的admin、user帳號可以順利下載下來外
只要是沒有登入帳號的用戶,每次都下載到11.4MB就斷掉了 (很怪吧~~)
不清楚是模組還是設定上的問題,所以想請教前輩是否還有哪邊需要設定,才可改善現況!

以下是我爬文後所變更過的設定檔內容:
修改檔案D:\AppServ\php5\php.ini-dist
修改前
post_max_size = 8M
upload_max_filesize = 2M
max_execution_time = 30
max_input_time = 60
memory_limit = 128M

修改後
post_max_size = 256M
upload_max_filesize = 256M
max_execution_time = 1000
max_input_time = 1000
memory_limit = 256M

看起來應該是跟 readfile 有關
下面是我在 PHP: readfile - Manual 找到的討論:

To anyone that's had problems with Readfile() reading large files into memory the problem is not Readfile() itself, it's because you have output buffering on. Just turn off output buffering immediately before the call to Readfile(). Use something like ob_end_flush().

我自己測試的結果
用 admin 帳號上傳了一個 60m 的檔案,上傳成功
直接點擊連結下載檔案,下載完成的檔案大小一致(60m)
換成一般帳號登入,下載的結果也相同
將 files 內的檔案複製出來並將檔名復原,檔案也是正常的

接著登出後
再次點擊下載的連結,不過檔案雖然下載完成,沒有錯誤訊息,但是大小只有 24m,檔案不完整
不過依照上面的資料在 readfile() 之前加上一行 ob_end_flush() 之後
訪客就可以正常下載,取得完整 60m 的檔案了

更新模組檔案之後再試試看吧

0.9-dev 版的修改:

最近 apple 出了 Safari 4.0
測試後發現
預設下載檔名經過 iconv 將 UTF-8 轉換成 BIG5
就可以正確顯示中文檔名

所以設置下載檔名的部份
依照 Safari 的版本做出修改
讓 4.x 以後版本的 Safari 輸出 iconv 轉換過的檔名

您好:
前幾個月有您的這各模組幫忙,才能順利上傳中文檔名。
前陣子因為要參加考試,所以一直在看書沒接觸Drupal~~~
如今考完試了,就又回頭過來接觸Drupal
我發現一個問題,就是 "無法開啟" 附件
如圖片,若點選 "開啟",會自動開啟該軟體(word、excel、pdf) 但就是無法開啟檔案。

在 PHP: readfile - Manual 找到的討論:

If you're passing files through a script, you may want to include this header:
header ("Cache-Control: must-revalidate, post-check=0, pre-check=0");
Otherwise, some programs such as Adobe Reader may have problems opening files directly.

跟這個問題蠻類似的
所以比照辦理,加上 header ("Cache-Control: must-revalidate, post-check=0, pre-check=0"); 之後用 ie6 測試
就可以正常開啟檔案了

另外 IE 下載檔名編碼的部份
原本使用的 rawurlencode 編碼方式變更為使用 iconv 將檔名轉為 BIG5
可以正常 開啟/下載 檔案
而且開啟的檔案檔名會正確的顯示中文
而非 rawurlencode 會直接顯示 url 編碼後檔名

前輩:
剛剛更新後進行測試,附件可以順利開啟了。
這各模組個人覺得可以放在模組區供有需要的人下載來使用!!

P.S:希望前輩日後有空時,能夠開發適用於Drupal 6.x版本的模組~~~

作者目前有開發出Drupal 5版本的,尚未開發出Drupal 6版本的...
所以你必須考量是否像我一樣非要不可 (我們那邊的user上傳檔名都是中文的)
為了使用這套模組,我直接改用Drupal 5~~
目前能完整解決中文檔名的問題,除了音譯模組Transliteration外,就只有這套了。