【问题标题】:How to set filename containing spaces in Content-Disposition header如何在 Content-Disposition 标头中设置包含空格的文件名
【发布时间】:2013-09-09 04:05:27
【问题描述】:

我有这段代码:

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

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

我们如何解决这个问题?

【问题讨论】:

    标签: java servlets download filenames


    【解决方案1】:

    使用引号:

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

    【讨论】:

    • 如果文件名中包含“怎么办?(在 Windows 中是不可能的,但 linux 文件的名称中可能包含 '"'。)
    • 根据 HTTP 1.1 规范,这是正确的方法(文件名值作为引用字符串):w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.5.1
    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

      需要以下步骤:

      • URI 编码 文件名
      • 替换编码文件名中的空格(我们使用的是 URL 编码器而不是 URI 编码器,但 URL 编码使用 + 作为编码空间而不是 %20,因此我们需要手动替换它们%20)。
      • 在标头中设置编码文件名。这里我们有两种变体:一种指定编码,另一种不指定。为了获得最大的兼容性,我们可以同时指定两者。

      代码:

      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

      成功测试

      • 火狐✔
      • 铬 ✔
      • 边缘 ✔
      • Internet Explorer ✔

      【讨论】:

      • 很遗憾,无法在 Safari 中正常工作。对于 Safari,您必须只有 filename* 或以纯 filename 部分传递 utf-8 名称
      【解决方案4】:

      如果你用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++ 中的工作原理相同......
      猜你喜欢
      • 1970-01-01
      • 2017-10-29
      • 2016-08-25
      • 2015-05-12
      • 2011-12-23
      • 1970-01-01
      • 2019-12-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多