如何在HTTP中编码Content-Disposition标头的filename参数?
想要强制下载而不是直接在Web浏览器中呈现资源的Web应用程序在HTTP响应中以以下形式发出" Content-Disposition"标头:
Content-Disposition:附件; filename = FILENAME
" filename"参数可用于建议浏览器将资源下载到其中的文件的名称。但是,RFC 2183(内容处置)在第2.3节(文件名参数)中指出,文件名只能使用US-ASCII字符:
Current [RFC 2045] grammar restricts parameter values (and hence Content-Disposition filenames) to US-ASCII. We recognize the great desirability of allowing arbitrary character sets in filenames, but it is beyond the scope of this document to define the necessary mechanisms.
但是,有经验证据表明,当今大多数流行的Web浏览器似乎都允许使用非US-ASCII字符,但是(由于缺乏标准)对文件名的编码方案和字符集规范存在分歧。问题是,如果文件名navefile(不带引号,并且第三个字母为U + 00EF)需要编码到Content-Disposition标头中,那么流行的浏览器采用了哪些方案和编码?
出于这个问题的目的,流行的浏览器是:
- 火狐浏览器
- IE浏览器
- 苹果浏览器
- 谷歌浏览器
- 歌剧
解决方案
我通常使用URL编码(用%xx编码)文件名,并且它似乎在所有浏览器中都有效。我们可能还是要进行一些测试。
在提议的RFC 5987"超文本传输协议(HTTP)标头字段参数的字符集和语言编码"中,对此进行了讨论,包括浏览器测试和向后兼容性的链接。
RFC 2183指出,此类标头应按照RFC 2184编码,而RFC 2231已弃用该RFC,而RFC草案已将其覆盖。
以下是Jim在回答中提到的RFC草案中链接的以下文档,它进一步解决了这个问题,在这里绝对值得直接注意:
HTTP Content-Disposition标头和RFC 2231/2047编码的测试用例
- 在Content-Disposition中没有可以互操作的方式来编码非ASCII名称。浏览器兼容性一团糟。
- 从理论上讲,在Content-Disposition中使用UTF-8的语法非常奇怪:
filename * = UTF-8'foo%c3%a4
(是的,这是一个星号,除了空的单引号外没有其他引号在中间) - 此标头不是一种相当标准的(HTTP / 1.1规范承认其存在,但不需要客户端支持它)。
有一个简单而强大的替代方法:使用包含所需文件名的URL。
当最后一个斜杠后的名称是我们想要的名称时,则不需要任何额外的标题!
此技巧有效:
/real_script.php/fake_filename.doc
如果服务器支持URL重写(例如Apache中的mod_rewrite),则可以完全隐藏脚本部分。
网址中的字符应采用UTF-8(逐字节urlencode编码):
/mot%C3%B6rhead # mot?rhead
在asp.net mvc2中,我使用类似以下内容:
return File( tempFile , "application/octet-stream" , HttpUtility.UrlPathEncode(fileName) );
我想如果我们不使用mvc(2),则可以使用
HttpUtility.UrlPathEncode(fileName)