-1

In the project I am working on we are building a feature where you have a file with 2 buttons. Button 1 opens the file in your browser, button 2 starts downloading the file. I see these as 2 distinct interactions.

We are using Angular 8 in the front-end and ASP.NET 3.0 in the back-end, but I think the front-end stack shouldn't matter since we can just get away with an <a> tag that points to the action where you download the file. No JS needed.

I know the user can decide in the browser what to do when downloading certain file types. For example, in firefox you can decide to open PDF fileswith the built-in pdf viewer, ask the user what to do, or point to some application that handles the action. But, Correct me if I am wrong!, I believe that this is for when a PDF is "downloaded to the browser", which is different than downloading it to the disk? I hope my code makes the matter more obvious.


The main question: Is it correct that the API has an option to return the file as to make it open in the browser or to download it to disk, or should the API just return the file and should the front-end handle the action that the buttons say they do?

If the answer is that the front-end should do all the magic, what return File() statement in my code below should be used?


The important part of my controller action looks like this:

URL: https://localhost:3435/api/foo/1/bar/download?openInBrowser=true

// Dummy code, we are downloading a file called Hello.pdf with the content-type application/pdf

var byteArray = GetBytesFromFile();
var contentType = GetContentTypeFromFile();
var fileName = GetFileNameFromFile();

if (openInBrowser)
{
    return File(byteArray, contentType);
}
else
{
    return File(byteArray, contentType, fileName);
}

Now, if you have the following HTML:

<a href="https://localhost:3435/api/foo/1/bar/download?openInBrowser=true">Open in browser</a>
<a href="https://localhost:3435/api/foo/1/bar/download?openInBrowser=false">Download</a>

Clicking on "Open in browser" results in the following in firefox using the built-in PDF viewer:

  • It opens the PDF in the built-in viewer
  • The response headers are the following using cUrl:
HTTP/1.1 200 OK
Date: Wed, 29 Apr 2020 11:11:24 GMT
Content-Type: application/pdf
Server: Kestrel
Content-Length: 161689
Content-Disposition: attachment; filename=Hello.pdf; filename*=UTF-8''Hello.pdf

Clicking on "Download" results in the following using firefox:

  • It asks me what to do with the file (This is a user specific setting)
  • If I select "save file", it saves it to my downloads folder and otherwise I select what application needs to handle the file.
  • Both options result in the same response headers:
HTTP/1.1 200 OK
Date: Wed, 29 Apr 2020 11:18:32 GMT
Content-Type: application/pdf
Server: Kestrel
Content-Length: 161689
Content-Disposition: attachment; filename=Hello.pdf; filename*=UTF-8''Hello.pdf

I hope my question is clear :)!

Thank you for your assistance

1
  • Are you sure you are getting those headers AND that behavior? Have you checked with browser development tools? Content-Disposition: attachment should always force a download. Btw if you don't use that header, you can request a same-origin download entirely on the frontend via the <a download> HTML attribute.
    – amon
    Apr 29 '20 at 12:33
0

From the server point of view there is no big difference between "download to browser" and "download to disk". Usually browsers that directly display some content also offer an option to save it to disc (and the content is not downloaded again but copied from browser cache).

Server can only give a recommendation via Content-Disposition header how browser should hande a file, as @amon mentioned (more info here). Experienced user can save or display the file in both cases no matter what you do. Two buttons are in my opinion useful only if you expect less experienced users. In this case you have no other option then implement it on server that only can set the Content-Disposition header. On the other hand there is no guarantee the browser will follow it – and if it will not it will be even more confusing for the user.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.