Java 如何在 Content-Disposition 标头中设置包含空格的文件名

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18634337/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 09:42:04  来源:igfitidea点击:

How to set filename containing spaces in Content-Disposition header

javaservletsdownloadfilenames

提问by Huy Than

I have this piece of code:

我有这段代码:

resp.addHeader("Content-Disposition", "inline; filename=" + fileName);

When the file name is "a_b_c.doc" or "abc.doc" the name of the downloaded file is displayed correctly. However, when the file name is "a b c .doc" the name of the downloaded file is only "a".

当文件名为“a_b_c.doc”或“abc.doc”时,正确显示下载文件的名称。但是,当文件名为“abc .doc”时,下载文件的名称仅为“a”。

How can we solve this?

我们如何解决这个问题?

回答by Moritz Petersen

Use quotes:

使用引号:

resp.addHeader("Content-Disposition", "inline; filename=\"" + fileName + "\"");

回答by Rapha?l

if you quote your filename with chr(34)it will work:

如果你引用你的文件名,chr(34)它将起作用:

resp.addHeader("Content-Disposition", "inline; filename=" + chr(34) + fileName + chr(34));

回答by Malvineous

According to the HTTP standardyou surround the string with double-quotes, and escape any quotes or backslashes within by preceding them with a single backslash.

根据HTTP 标准,您用双引号将字符串括起来,并通过在它们前面加上一个反斜杠来转义其中的任何引号或反斜杠。

Content-Disposition: attachment; filename="Very \"interesting\" file \ files.txt"

This will prompt to save as Very "interesting" file \ files.txt. Note that the presence of a backslash does not suggest a folder, it suggests the backslash is part of the filename (which is perfectly valid on Linux and some other platforms, but not on Windows.)

这将提示另存为Very "interesting" file \ files.txt. 请注意,反斜杠的存在并不表示文件夹,它表明反斜杠是文件名的一部分(这在 Linux 和其他一些平台上完全有效,但在 Windows 上无效。)

回答by Peter Walser

Following steps are required:

需要以下步骤:

  • URI-encodethe filename
  • Replace the spacesin the encoded filename (we're using an URL encoder instead of URI encoder, but URL encoding uses +as encoded space instead of %20, so we need to manually replace them with %20).
  • Set the encoded file name in the header. Here we have two variants: one which specifices the encoding, and one that doesn't. For maximal compatibility we can specify both.
  • URI 编码文件名
  • 替换编码文件名中的空格(我们使用的是 URL 编码器而不是 URI 编码器,但 URL 编码使用的+是编码空间而不是%20,因此我们需要手动将它们替换为%20)。
  • 在 header 中设置编码的文件名。这里我们有两种变体:一种指定编码,一种不指定。为了最大的兼容性,我们可以同时指定两者。

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));

Example header: inline; filename*=UTF-8''Hello%20World.doc; filename=Hello%20World.doc

示例标题: inline; filename*=UTF-8''Hello%20World.doc; filename=Hello%20World.doc

Successfully tested with

成功测试

  • Firefox ?
  • Chrome ?
  • Edge ?
  • Internet Explorer ?
  • 火狐?
  • 铬合金 ?
  • 边缘 ?
  • IE浏览器 ?