8

I've got a rather odd situation happening, that I'm having difficulty tracking down in an existing Django application. One of the views, which inherits from APIView, returns with a file when a user makes a POST call. The endpoint works fine, but there's something odd happening when the downloaded file reaches the client machine. By the time the browser receives the file, the file extension has been renamed with a trailing underscore. (So suppose the file was originally "test.txt", the version that the client receives would be "test.txt_").

As near as I can figure, just before the response object is returned in the APIView, the content-type and content-disposition headers look correct. E.g.:

Content-Type: application/octet-stream
Content-Disposition: attachment;filename="test.txt"

That same file, when it shows up in Chrome downloads, is named "test.txt_" - with the trailing underscore. I've tried the same thing out in Firefox, and it seems to download correctly. Unfortunately, telling the majority of our users to switch browsers isn't going to fly.

I have tried:

  • Forcing a different content type (e.g.: instead of "application/octet-stream", try "application/text", just to see what happens). This had no effect.
  • Formatting the content disposition slightly different (e.g.: space between the semicolon and filename). This also had no effect.
  • Removed the double quotes around the filename in the content-disposition header. No effect.
  • Dropping breakpoints within the Rest Framework itself, but Visual Studio Code doesn't seem to trigger on these. (I'm not super-familiar with debugging through Visual Studio Code, so this may be my fault).
  • Stripped out any custom middleware, so the only remaining middleware are as follows:
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

So far, any similar issues that other people have experienced seem to be slightly different (i.e.: Internet Explorer removing the period in the extension and replacing it with an underscore).

Any guesses on what might be happening here? I'm a bit stumped.

Joel B
  • 801
  • 1
  • 11
  • 30

8 Answers8

5

You have to remove "" from your file name

Change attachment; filename="filename.txt" to attachment; filename=filename.txt

Although seems like you won't be able to have spacing in file name

Vasyl Kobetiak
  • 221
  • 4
  • 4
  • 1
    This was the answer for me. I solved it with this ugly javascript (ES6 required): `const filename = response.headers.get('Content-Disposition')?.split(';')?.[1]?.split('=')?.[1]?.slice(1, -1);` – xaphod Nov 02 '22 at 17:17
4

I finally figured out what was going on here. The UI that was used to trigger the download was doing so through creating a temporary anchor tag (see the second answer here: Download data url file ). When it was doing so, it had two different cases. In one case, if downloading multiple files, it would change the file extension to .zip. In another case, if downloading a single file, it was still trying to append an extension, but the way the UI code was written, it was setting the extension to be an empty string. So the end result is a period being added, but no extension after that. For example, if the file being downloaded was "test.txt", it would end up as "test.txt.", which was then converted by Chrome to "test.txt_", on Windows, to make it a valid file extension.

Joel B
  • 801
  • 1
  • 11
  • 30
  • Do you know how to remove it? – codexplorer Sep 25 '19 at 05:15
  • In our case, it ended up being a change in the UI code to quit putting on a trailing period. – Joel B Sep 25 '19 at 17:23
  • 1
    Too bad, that's not enough. I am looking for a way to remove the preceding and trailing underscore. – codexplorer Sep 26 '19 at 01:57
  • If you make the same request via CURL or Postman, do you get the same results? – Joel B Sep 26 '19 at 20:57
  • In fact, I am writting a service with python bottle and could let users download some files after a request. I would like to use its builtin function, static_file, and got the situation both of us met. I didn't try CURL or Postman because those are not in my toolkits. I am still looking for a way to work around it. But so far, it's a long shot. – codexplorer Sep 27 '19 at 03:37
  • 2
    I found that the user driven file name had spaces in it, told them not to do that and the problem went away. – Kris Kilton Jul 09 '20 at 18:42
2

Our environment has a document storage system that contains documents with the attributes DocumentName and ContentType. In some cases, the content type would return with spaces appended to the end of the string like "pdf ".

In Internet Explorer the output would truncate the end of the string while Chrome would convert the extra spaces to underscores giving me this filename: "file.pdf______________"

To resolve I simply truncate the string.

public string getFileName(string docName, string contentType) {
    string fileName = docName + "." + contentType.Trim();

    return fileName;
}
Tim
  • 88
  • 1
  • 1
  • 7
1

I encountered the same problem. Let's say your download file name is "my_report.csv" Then before doing the download operations get rid of " characters

fileName  = fileName.replace('"','') // replacing one " charcter
fileName  = fileName.replace('"','') // replacing second " character

This will resolve your issue.

shashika11
  • 179
  • 2
  • 5
0

My solution in ASP.NET core

[HttpGet("pdf/{fileId}")]
public IActionResult GetPdfFile([FromRoute]int fileId)
{
    var result = Repo.GetFile(fileId);
    Response.Headers.Add("Content-Disposition", $"inline; filename={result.FileName}");
    return File(result.Data, "application/pdf");
}
Raskolnikov
  • 3,791
  • 9
  • 43
  • 88
0

I resolved this issue with replace white space in file name by a character like -.

Corné
  • 1,304
  • 3
  • 13
  • 32
0

This was happening for me when the filename included a comma.

    lastname,MD.pdf

browser would download filestream as

    _lastname,MD.pdf_ 

Adding code to remove a potential comma from the filename resolved the issue and made it download as expected.

    filename = filename.Replace(",", ""); // replace comma characters with blank

now downloads as

    lastnameMD.pdf
0

In my case there was a space as a first character, and it was replaced to underscore. So I simply removed the space :-)

ArturOlszak
  • 2,653
  • 2
  • 21
  • 20