負責的網站在ASP.NET網頁有一段下載Word/Excel檔案的程式碼,最近使用者要求的檔案名稱內含繁體中文字,
同事用chrome/firefox瀏覽器測試下載都很正常顯示,但用IE(版本11)開啟時,卻出現了亂碼。
1.準備一個中文檔名的檔案
2.在HomeControler中加入下載程式碼Download
public ActionResult Download()
{
//檔案位置
string filepath = @"E:\test\WebApplication1\中文檔名.docx";
//檔案名稱
string filename = Path.GetFileName(filepath);
//讀成串流
Stream sfilestream = new FileStream(filepath, FileMode.Open, FileAccess.Read, FileShare.Read);
//回傳出檔案
return File(sfilestream, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", filename);
}
3.執行下載
檔名正常顯示中文!
4.先增一支Download.aspx
在Page load加入下載程式碼
protected void Page_Load(object sender, EventArgs e)
{
string filepath = @"E:\test\WebApplication1\中文檔名.docx";
string fileName = Path.GetFileName(filepath);
HttpContext.Current.Response.AppendHeader("content-disposition", "attachment;filename=" + fileName);
HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
HttpContext.Current.Response.WriteFile(filepath);
HttpContext.Current.Response.End();
}
5.執行下載
檔名不正常
- 將中文檔名用HttpUtility.UrlEncode以UTF8編碼系統進行QP編碼。
- HeaderEncoding編碼改為BIG5。
string fileName = HttpUtility.UrlEncode(Path.GetFileName(filepath));
//string fileName = Path.GetFileName(filepath);
HttpUtility.UrlEncode預設會以UTF8的編碼系統進行QP(Quoted-Printable)編碼,可以直接顯示的7 Bit字元(ASCII)就不用特別轉換。
- 編碼前:中文檔名.docx
- 編碼後:%e4%b8%ad%e6%96%87%e6%aa%94%e5%90%8d.docx
除了標準ASCII,其他都會用UTF8進行編碼送到前端瀏覽器。
https://mothereff.in/utf-8
檔名可以正常顯示中文了!
增加一行設定HeaderEncoding的程式碼,因為伺服器都是繁體中文,預設Encoding.Default = BIG5
HttpContext.Current.Response.HeaderEncoding = System.Text.Encoding.Default;
預設HttpContext.Current.Response.HeaderEncoding是UTF8,將編碼改為BIG5也可以解決中文檔名問題
都已經是UTF8編碼的網頁了,為什麼還得要將HeaderEncoding編碼改為繁體中文作業系統的BIG5才能解決???
進一步搜尋到保哥、黑暗大文章,看起來似乎與瀏覽器支援到哪一種Content-Disposition標準有關(RFC2045、2183、5987)。
好,先到此打住,來看奧運了!以後有時間再繼續深入調查。
小結:
- 因為系統被要求要支援多國語系,暫時我們選擇第一種解法,以後出現蝌蚪文還是火星文就不怕了。
- ASP.NET MVC已經解決了檔名有中文碼問題了。
參考:
KB-Open And Download File In Chinese Filename
ASP.NET 如何設定強制下載檔案並正確處理中文檔名的問題
How to encode the filename parameter of Content-Disposition header in HTTP?