下載檔名亂碼怎麼查:核Content-Disposition與UTF-8

網站上的下載連結寫「模板檢查表」,存到電腦後卻變成一串百分比編碼,或只剩download.csv。先別重新壓縮整包檔案:瀏覽器採用的檔名,可能來自下載回應的Content-Disposition,與頁面上的連結文字不同。

這篇處理下載檔名與UTF-8編碼。檔案能否下載、會員是否有權限,則屬於另外的功能;檔名顯示正常,也不能證明下載內容正確。

先分清檔名與檔案內容

下載後,先看錯的是「名稱」還是「打開後的文字」。CSV內中文字亂碼,可能要查檔案實際位元組與開啟軟體;檔案內容正常、名稱卻奇怪,則先查回應標頭。不要把CSV內容加了UTF-8設定,就認定檔名一定跟著修好。

另外記下來源網址與瀏覽器。下載可能經過重新導向,真正送出檔案的是最後一個回應;查看第一個入口的標頭,未必看得到檔名設定。頁面上的下載按鈕文字,也不等於伺服器建議的名稱。

在最後一個回應找Content-Disposition

開啟瀏覽器開發者工具的Network,保留請求記錄,再按下載。找到真正回傳檔案的請求,讀Response Headers。例如:

Content-Type: text/csv; charset=utf-8
Content-Disposition: attachment; filename="template-check.csv"

attachment表示以附件處理,filename提供建議名稱。這份例子只提供ASCII名稱,所以中文標題不會自動出現在下載檔名。實際儲存行為仍由瀏覽器與檔案系統處理,不要把它當成可以指定訪客電腦完整路徑的指令。

若沒有這個標頭,瀏覽器可能依URL或其他條件取得名稱。先記錄目前回應,不必立刻到所有頁面加相同屬性;請維護下載程式的人核對真正送檔的入口。

中文名稱放在filename*,保留簡單備用檔名

需要非ASCII名稱時,可由回應提供filename*,使用指定字元編碼及百分比編碼。下面同時保留英文備用名稱,中文部分代表「模板檢查.csv」:

Content-Disposition: attachment; filename="template-check.csv"; filename*=UTF-8''%E6%A8%A1%E6%9D%BF%E6%AA%A2%E6%9F%A5.csv

UTF-8''後方是UTF-8檔名的編碼,不是把中文字隨便塞進標頭。支援這個參數的處理端會優先使用filename*;保留ASCII的filename,可讓不理解擴充寫法的處理端還有合理名稱。

注意兩個單引號的位置,也不要同時輸出兩個相同的filename*。如果使用的框架已有下載回應方法,先查它如何接收Unicode檔名與產生標頭,不要在既有設定後再手動追加一份,造成重複參數。

百分比編碼只做一次

常見失誤是先把檔名編成%E6...,再交給會自行編碼的程式。第二次把百分比符號變成%25,瀏覽器解碼一次後,仍得到一串%E6...,而非原本的中文。

可先用JavaScript查看一次編碼的結果,但實際標頭仍由下載伺服器產生:

encodeURIComponent('模板檢查.csv');
// %E6%A8%A1%E6%9D%BF%E6%AA%A2%E6%9F%A5.csv

這個例子不包含撇號等需要額外處理的字元,不能把它當成完整通用的Content-Disposition產生器。正式程式應使用框架或函式庫提供的標頭編碼方法,先確認輸入要的是原始Unicode名稱,還是已編碼字串。

不要把擴充參數的寫法直接搬進普通filename。百分比編碼在filename中的處理並非所有瀏覽器一致,可能一個瀏覽器看起來正常,另一個保留原字串。可預期的ASCII備用名稱,比把同一串編碼塞進兩個欄位更容易維護。

用同一份內容,確認改的是哪一層

準備一份不含客戶資料的小檔案,做三個測試回應:只有ASCII備用名稱、filename*編碼一次、filename*重複編碼。檔案內容保持完全相同,再比較瀏覽器建議名稱與下載後的內容。

本文CSV案例的三個入口送出相同位元組;Chromium取得的名稱依序是template-check.csv、模板檢查.csv與仍帶百分比文字的名稱。這能分清標頭造成的差異,不代表所有瀏覽器都會給出相同結果。

保存下載檔後,再以同一種方式查看內容或計算雜湊。若三份內容相同,就別把名稱修正說成資料修復。反過來,如果內容也不同,回頭查是否拿到了登入頁、錯誤訊息或另一個檔案,不能只靠副檔名判斷。

別把路徑與私人資料當成檔名

檔名只需要識別文件。避免使用完整伺服器路徑、私人Email或客戶識別碼,也不要相信使用者傳入的檔名可以直接寫進標頭。保留合理副檔名,清理控制字元與路徑分隔符;下載目標仍由功能自己的資料與授權流程決定。

瀏覽器可能為配合檔案系統調整不允許的字元。同名檔案已存在時,儲存端也可能加序號。看到「模板檢查(1).csv」,先確認是否是本機已有同名檔,而不是立刻判定伺服器又多編碼一次。

修正前保存原下載回應設定和標頭,只改一個測試入口。用自己的正式支援瀏覽器重試中文、空白與ASCII名稱,確認內容、格式、檔名都正確,再擴大到其他下載功能。

如果檔名正常卻無法下載,請另查回應狀態與下載行為;如果內容開啟後亂碼,則把實際檔案交給負責內容編碼的人。這樣維護者知道應該修標頭、檔案位元組,還是下載功能本身。

參考資料

原文鏈接:https://wntheme.com/download-filename-content-disposition/,轉載請註明出處。
0

評論0

顯示驗證碼
沒有帳號?註冊  忘記密碼?