Windows 上的 Chrome 向下载的文件添加尾随下划线?

Joe*_*l B 6 google-chrome http-headers

我遇到了一个相当奇怪的情况,我很难在现有的 Django 应用程序中进行跟踪。其中一个从 APIView 继承的视图在用户进行 POST 调用时返回一个文件。端点工作正常,但是当下载的文件到达客户端机器时会发生一些奇怪的事情。当浏览器接收到文件时,文件扩展名已被重命名为尾随下划线。(因此假设文件最初是“test.txt”,客户端收到的版本将是“test.txt_”)。

据我所知,就在 APIView 中返回响应对象之前,content-type 和 content-disposition 标头看起来是正确的。例如:

Content-Type: application/octet-stream
Content-Disposition: attachment;filename="test.txt"
Run Code Online (Sandbox Code Playgroud)

同一个文件,当它出现在 Chrome 下载中时,被命名为“test.txt_” - 尾随下划线。我在 Firefox 中尝试过同样的事情,它似乎可以正确下载。不幸的是,告诉我们的大多数用户切换浏览器是行不通的。

我试过了:

  • 强制使用不同的内容类型(例如:而不是“application/octet-stream”,尝试“application/text”,看看会发生什么)。这没有效果。
  • 格式化内容配置略有不同(例如:分号和文件名之间的空格)。这也没有效果。
  • 删除了 content-disposition 标题中文件名周围的双引号。没有效果。
  • 在 Rest Framework 本身中删除断点,但 Visual Studio Code 似乎不会触发这些断点。(我不太熟悉通过 Visual Studio Code 进行调试,所以这可能是我的错)。
  • 去掉了任何自定义中间件,所以剩下的唯一中间件如下:
corsheaders.middleware.CorsMiddleware
django.contrib.sessions.middleware.SessionMiddleware
django.middleware.locale.LocaleMiddleware
django.middleware.common.CommonMiddleware
django.middleware.csrf.CsrfViewMiddleware
django.contrib.auth.middleware.AuthenticationMiddleware
django.contrib.messages.middleware.MessageMiddleware
Run Code Online (Sandbox Code Playgroud)

到目前为止,其他人遇到的任何类似问题似乎都略有不同(即:Internet Explorer 删除了扩展中的句点并将其替换为下划线)。

对这里可能发生的事情有任何猜测吗?我有点难住了。

小智 9

您必须从文件名中删除“”

改成attachment; filename="filename.txt"attachment; filename=filename.txt

虽然看起来文件名中不能有空格

  • 这就是我的答案。我用这个丑陋的javascript(需要ES6)解决了这个问题: `const filename = response.headers.get('Content-Disposition')?.split(';')?.[1]?.split('=')? .[1]?.slice(1, -1);` (2认同)

Joe*_*l B 4

我终于明白这是怎么回事了。用于触发下载的 UI 是通过创建临时锚标记来实现的(请参阅此处的第二个答案:下载数据 url 文件)。当它这样做时,有两种不同的情况。在一种情况下,如果下载多个文件,它会将文件扩展名更改为 .zip。在另一种情况下,如果下载单个文件,它仍然尝试附加扩展名,但 UI 代码的编写方式是将扩展名设置为空字符串。所以最终的结果是添加了一个句点,但之后不再延长。例如,如果正在下载的文件是“test.txt”,那么它最终会是“test.txt”,然后在 Windows 上由 Chrome 转换为“test.txt_”,以使其成为有效的文件扩展名。

  • 我发现用户驱动的文件名中有空格,告诉他们不要这样做,问题就消失了。 (2认同)