如何在浏览器的文件下载框中显示非ASCII文件名?

时间:2020-03-06 14:52:43  来源:igfitidea点击:

似乎没有一种公认的方式来发送非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投诉。