如何在Content-Disposition标头中设置含有空格的文件名
回答 4
浏览 2.6万
2013-09-05
我有这样一段代码:
resp.addHeader("Content-Disposition", "inline; filename=" + fileName);
当文件名为 "a_b_c.doc "或 "abc.doc "时,下载的文件名会正确显示。然而,当文件名是 "a b c .doc "时,下载的文件名只有 "a"。
我们怎样才能解决这个问题呢?
4 个回答
#1楼
得票数 87
使用引号:
resp.addHeader("Content-Disposition", "inline; filename=\"" + fileName + "\"");
如果文件名里有"怎么办?(这在windows系统中是不可能的,但linux系统的文件可能在其名称中含有'"'。)
- Bor691 2014-03-09
根据HTTP 1.1规范,这是正确的方式(文件名值为引号字符串):w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.5.1
- betatester07 2016-06-01
#2楼
得票数 17
根据HTTP标准,你要用双引号包围这个字符串,并通过在其前面加一个反斜杠来转义任何引号或反斜杠。
Content-Disposition: attachment; filename="Very \"interesting\" file \\ files.txt"
这将提示保存为Very "interesting" file \ files.txt
。请注意,反斜杠的出现并不表明是一个文件夹,它表明反斜杠是文件名的一部分(这在Linux和其他一些平台上是完全有效的,但在Windows上不是。)
#3楼
得票数 2
需要采取以下步骤:
- URI-encode的文件名
- 替换编码文件名中的空格(我们使用的是URL编码器,而不是URI编码器,但是URL编码使用
+
作为编码空格,而不是%20
,所以我们需要手动替换为%20
)。 - 在头文件中设置编码的文件名。这里我们有两种变体:一种是指定编码,另一种是不指定编码。为了达到最大的兼容性,我们可以同时指定这两种方式。
Code:
String fileName = ...;
String encodedFileName = URLEncoder.encode(fileName,
StandardCharsets.UTF_8.name()).replace("+", "%20");
response.setHeader("Content-Disposition",
String.format("inline; filename*=UTF-8''%1$s; filename=%1$s", encodedFileName));
头部示例:inline; filename*=UTF-8''Hello%20World.doc; filename=Hello%20World.doc
成功测试了
- Firefox ✔
- Chrome ✔
- Edge ✔
- Internet Explorer ✔
不幸的是,在Safari中不能正常工作。你必须只有文件名*或在Safari浏览器中传递utf-8名称的普通
filename
部分。
- Alexander Goldabin 2020-11-10
#4楼
得票数 0
如果你用chr(34)
引用你的文件名,它就会起作用:
resp.addHeader("Content-Disposition", "inline; filename=" + chr(34) + fileName + chr(34));
chr(34)
在PHP中是存在的,但这是一个Java问题,这在Java中不起作用。在Java中,你需要用(char) 34
来代替。但拜托,除非你脑子里有ASCII表,否则这段代码是无法阅读的。为什么不在需要双引号的时候直接使用双引号呢?当然,你需要转义,即像"this is my \"quoted\" string"
那样在前面加一个反斜杠。这样做更有可读性,而且在Java、PHP、C++中的效果都一样。
- Christopher K. 2018-09-06