随笔 - 42  文章 - 71  trackbacks - 0
<2012年2月>
2930311234
567891011
12131415161718
19202122232425
26272829123
45678910

常用链接

留言簿

随笔档案

文章分类

文章档案

搜索

  •  

最新评论

阅读排行榜

评论排行榜

首先声明,这个问题,只在IE6上会发生,IE8上是没有此问题的,IE7未测试。
IE6是一个很奇怪的东西,估计很多开发人员对于IE6是非常头疼的。貌似微软一向喜欢弄这样的幺蛾子,就像当年的Microsoft JVM + Visual J++,虽然是好东西,但是由于未遵循标准规范,被Java组织给踢了出去,然后就不了了之了。

现在的应用中,文件下载的功能是很常见的。通常的做法是,文件被存放在服务器的某个路径,然后由应用去读取文件,再通过设置响应头来让浏览器进行响应的动作。如果希望浏览器能够识别文件名,通常的做法是设置响应头中的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”。

通常,这种模式是没有问题的,但是如果文件名很长,就会出现“无法下载文件”的错误。

经过查找资料,在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这个响应头,IE6仅能处理150字节左右,再长了就处理不了了。对于如何解决这个问题,微软的原文中也是闪烁其词,说是有一个Hotfix,但是又说需要进一步测试……

如何解决问题呢?尝试在Web上放置一个很长中文名得文件,然后直接在IE6地址栏中输入这个文件的全地址,下载、直接打开都是正常的。因为这种情况下,服务器给出的响应中不包含Content-Disposition段,估计是浏览器发现这是一个二进制流,然后就将URL中后面的部分当做文件名,所以文件名的处理都是浏览器在本地完成的,所以就避免了上面文档中提到的BUG。(此处纯属猜想)

所以,解决的思路如下:
1. 在页面上生成的附件链接中,包含附件的ID信息以及文件名。例如:<a href="/web/attachmentDownload/id/attachmentName.zip">附件</a>
2. 在服务器端做一个Servlet,映射到路径 /attachmentDownload/*
3. Servlet获取到请求的URL,解析出附件的ID信息及文件名
4. Servlet设置响应头 response.setContentType("application/octet-stream") ,或者设置成附件对应的真实MIME-TYPE也可以。但是不设置Content-Disposition
5. 根据ID读取文件,向响应中写入文件流
6. flush

测试了一下,是有效的一个办法。但是为神马觉得这个解决办法奇怪的很?简直有点不像正常人类的思维方式了-_-|||
就这样吧,神马都是浮云!

posted on 2012-02-29 21:45 YODA 阅读(1414) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航: