如何在浏览器的文件下载框中显示非ASCII文件名?
似乎没有一种公认的方式来发送非ascii格式的标头参数。
文件下载的标头通常看起来像
内容配置:附件; filename =" theasciifilename.doc"
除非我们在filename参数中粉碎utf8编码的字符串,否则Firefox会很好地处理它,而IE会抛出该错误。
CodeProject上有一个文档,解释了一种编码文件名的方法。
本文档通过十六进制编码字节将B?n Ki?m K.doc编码为B%e1%ba%a3n%20Ki%e1%bb%83m%20K%c3%aa.doc。
问题1:该字符串中的第一个字符:的值-enx以十六进制表示该数字,则我们得到%a3%1e。这个人是怎么得到%e1%ba%a3的? (我显然在这里缺少一些简单的东西)
问题2:虽然IE承认这种编码,但Firefox却没有!该怎么办?
解决方案
在上面的链接中,e1 ba a3是提到的字符的UTF-8编码,而不是字符代码。
问题1的答案:我们将Unicode和UTF-8混淆了。 "?"的十六进制值是0xA31E,但这不是UTF-8字符。在UTF-8中,该字符需要三个字节,即" 0xE1 0xBA 0xA3"。对于非ASCII编码,URL编码定义不佳,但是%e1%ba%a3是用于该字符的有效UTF-8编码。
对问题2的回答(某种):
由于我们发现一个浏览器中的命名方案在另一浏览器中不起作用,因此唯一的解决方案是针对每个浏览器以不同的方式进行命名,类似于此处的示例。
万一链接消失,解决方案基本上是:
1. If browser is IE URL encode filename 2. Generate Content-disposition header
当然,通过用户代理确定浏览器是否为IE(这是我们可以使用的唯一方法)充满了各种常见的危险。
听起来像是以北美为中心,如果我们不能控制可能阻止或者修改了User-agent的大量浏览器中的这项工作很重要,则只需避免在文件名中使用UTF-8编码的字符,并且始终使用"下载"之类的东西。
规范基本上不允许US-ASCII以外的任何其他内容。 HTTP标头是US-ASCII。 HTTP的有效负载默认为ISO 8859-1,但这是指内容正文,而不是标头。
可以说,正确的做法是使用MIME技术对标头中的非ASCII数据进行编码,如RFC 2047中所述,但我不知道浏览器是否真正支持该技术。
编辑:糟糕,不,RFC 2047第5节明确指出Content-Disposition中不允许使用编码形式。看起来我们不走运,没有标准。
编辑2:有一个标准的RFC 2231定义了现在应该如何工作。它已获得某些浏览器的支持,但IE中不支持。我发现了一些测试案例,这些案例演示了它是如何工作的以及提供了哪些浏览器支持。
对于问题2,我们需要对Internet Explorer和Firefox的文件名进行URL编码。唯一的区别是我们需要在Firefox中使用RFC 2231的格式。
这适用于Firefox 3和Internet Explorer 7.
不幸的是,目前还没有一种方法可以在所有用户代理中使用。
有关测试用例,请参见http://greenbytes.de/tech/tc2231/,然后向Microsoft,Google和Apple投诉。