首先聲明,這個問題,只在IE6上會發(fā)生,IE8上是沒有此問題的,IE7未測試。
IE6是一個很奇怪的東西,估計很多開發(fā)人員對于IE6是非常頭疼的。貌似微軟一向喜歡弄這樣的幺蛾子,就像當年的Microsoft JVM + Visual J++,雖然是好東西,但是由于未遵循標準規(guī)范,被Java組織給踢了出去,然后就不了了之了。
現(xiàn)在的應(yīng)用中,文件下載的功能是很常見的。通常的做法是,文件被存放在服務(wù)器的某個路徑,然后由應(yīng)用去讀取文件,再通過設(shè)置響應(yīng)頭來讓瀏覽器進行響應(yīng)的動作。如果希望瀏覽器能夠識別文件名,通常的做法是設(shè)置響應(yīng)頭中的Content-Disposition屬性:
response.setContentType("application/octet-stream");
response.addHeader("Content-Disposition", "attachment; filename=xxx.xls");
如果要能夠讓IE正確的處理中文文件名,則需要對中文文件名進行UTF-8編碼:
response.addHeader("Content-Disposition", String.format("attachment;filename=%s", java.net.URLEncoder.encode("中文.xls", "UTF-8")));
編碼后的“中文.xls”為:“%E4%B8%AD%E6%96%87.xls”。
通常,這種模式是沒有問題的,但是如果文件名很長,就會出現(xiàn)“無法下載文件”的錯誤。
經(jīng)過查找資料,在IE6上存在這樣的問題,微軟的文檔(http://support.microsoft.com/kb/816868?LN=en-us)中說:
This behavior occurs because the content disposition header for the file stream is greater than approximately 150 bytes and the Latin character set is equal to 150 characters. This behavior may occur if the content disposition header is formatted with a non-Latin character set, such as Japanese or Russian.
For example, a 17-character content disposition header in the Japanese character set is 153 bytes because the UTF-8 encoding scheme uses 9 bytes to represent a single Japanese character, but it uses only 1 byte in the Latin character set.
也就是說,對于Content-Disposition這個響應(yīng)頭,IE6僅能處理150字節(jié)左右,再長了就處理不了了。對于如何解決這個問題,微軟的原文中也是閃爍其詞,說是有一個Hotfix,但是又說需要進一步測試……
如何解決問題呢?嘗試在Web上放置一個很長中文名得文件,然后直接在IE6地址欄中輸入這個文件的全地址,下載、直接打開都是正常的。因為這種情況下,服務(wù)器給出的響應(yīng)中不包含Content-Disposition段,估計是瀏覽器發(fā)現(xiàn)這是一個二進制流,然后就將URL中后面的部分當做文件名,所以文件名的處理都是瀏覽器在本地完成的,所以就避免了上面文檔中提到的BUG。(此處純屬猜想)
所以,解決的思路如下:
1. 在頁面上生成的附件鏈接中,包含附件的ID信息以及文件名。例如:<a href="/web/attachmentDownload/id/attachmentName.zip">附件</a>
2. 在服務(wù)器端做一個Servlet,映射到路徑 /attachmentDownload/*
3. Servlet獲取到請求的URL,解析出附件的ID信息及文件名
4. Servlet設(shè)置響應(yīng)頭 response.setContentType("application/octet-stream") ,或者設(shè)置成附件對應(yīng)的真實MIME-TYPE也可以。但是不設(shè)置Content-Disposition
5. 根據(jù)ID讀取文件,向響應(yīng)中寫入文件流
6. flush
測試了一下,是有效的一個辦法。但是為神馬覺得這個解決辦法奇怪的很?簡直有點不像正常人類的思維方式了-_-|||
就這樣吧,神馬都是浮云!
posted on 2012-02-29 21:45
YODA 閱讀(1434)
評論(0) 編輯 收藏