同事今天問了一個有趣的問題,有一個網頁檔"作業.htm",網頁裡有個圖檔叫"松鼠.jpg"。放在IIS的目錄下,開啟IE,URL輸入 http://myServer/作業.htm會傳回HTTP 404 找不到,但如果輸入http://myServer/松鼠.jpg則能正確Show圖!

一開始的質疑是,為什麼htm跟jpg的中文檔名處理原則不一樣? 不過想了想,htm又不是asp/asp.net會由另外的ISAPI程序處理,對IIS來說,都是讀取檔案再BinaryWrite罷了,為什麼會有如此差別待遇?

開啟Fiddler追蹤的結果,二個Request分別是
GET /%E4%BD%9C%E6%A5%AD.htm HTTP/1.1
GET /%E6%9D%BE%E9%BC%A0%.jpg HTTP/1.1

IE很忠實地將作業松鼠兩個字解析成UTF-8後以每個字三個Byte的十六進位碼傳回(想了解中文字如何解成UTF-8,可以參考我的中文編碼解析工具)。接著我到IIS上開啟Process Monitor,則發現當存取http://myServer/作業.htm時,IIS試圖去找一個檔名有亂碼的HTM檔案(雿平.htm),莫非---中文編碼解析錯誤? UTF-8被當成BIG5解了?

於是我把htm vs jpg的問題焦點改移到中文檔名所用的字上,多方排序組合測試的結果是,不管htm或jpg,只要檔名中有""這個字,就會發生檔案找不到的問題。而我的推論是,這種%E4%BD%9C%E6%A5%AD的資料對IIS來說,跟不知道語系編碼的狀況下要去讀檔案一樣,得靠一些特徵去"猜"是哪種編碼,而"業"的%E6%A5%AD剛好被判定成是Big5吧!

用我的中文編碼解析工具去看"雿平"三個字(第二字看不到),它的Big5碼不偏不倚,剛好就是%E4%BD%9C%E6%A5%AD,Bingo!!

所以我們可以確認,這個問題發生的原因是IE送出的中文檔名UTF-8編碼被IIS誤解為Big5。但IE為什麼要雞婆地將中文變成UTF-8呢? IE在進階設定的地方有個"Always send URLs as UTF-8"(愛台灣版為"永遠將URL傳送成UTF-8"),不知那一版本的IE起,這個設定預設為true。只要把這個設定關閉,http://myServer/作業.htm會送出
GET /作業.htm HTTP/1.1
反而不會出現誤解中文編號的問題,但這種方式不是所有Web Server都可以接受。

不過,面對中文檔名所帶來的諸多困擾,我建議的根本解決之道是:

1.避免使用中文檔名! 這是治本的方法,反正使用者都是靠Link連過來,用中文檔名對可讀性沒啥幫助
2.URL中如要加入中文,請使用JavaScript escape函數或ASP/ASP.NET Server.UrlEncode加入編碼


Comments

# by

你好~我想請問一下 為什麼我使用 Response.AddHeader("content-disposition", "attachment;filename=" & HttpUtility.UrlEncode(filename)) 會跳出選擇開啟或下載的視窗 其中的檔名是正常的中文 但又當按下開啟檔案時檔名又會變成亂碼 %22%22這樣UTF化的中文 但是使用http://localhost/測試檔.xls 這樣的下載方式 按下開啟後 檔名仍然是正常中文呢?

# by 123

123

Post a comment