如何在HTTP中编码Content-Disposition标头的filename参数?

时间:2020-03-06 14:21:53  来源:igfitidea点击:

想要强制下载而不是直接在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)