18

I want to be able to download a web file, but when the download dialog open, the filename is renamed.

Ex: File: http://<server>/<site>/test.txt

and when I click to download the file, download dialog open with the file name: test001.txt.

How can I achive that?

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
bruno2007
  • 181
  • 1
  • 1
  • 3

7 Answers7

23

As InviS suggests, now there's a download attribute on links.

Example:

<a href="http://server/site/test.txt" download="test001.txt">Download Your File</a>
Dmitry Pashkevich
  • 13,431
  • 9
  • 55
  • 73
12

You can used the download attribute on a link tag <a href="http://server/site/test.txt" download="test001.txt">Download Your File</a>

However, when content-disposition header is set on the server response, it will ignore the download attribute and the filename will be set to the filename in the content-disposition response header

You can accomplish this using axios, or any other fetch by doing this:

const downloadAs = (url, name) => {
  Axios.get(url, {
    headers: {
      "Content-Type": "application/octet-stream"
    },
    responseType: "blob"
  })
    .then(response => {
      const a = document.createElement("a");
      const url = window.URL.createObjectURL(response.data);
      a.href = url;
      a.download = name;
      a.click();
    })
    .catch(err => {
      console.log("error", err);
    });
};

usage:

downloadAs('filedownloadlink', 'newfilename');

Note: if your file is large, it will look like it is not doing anything until the whole file has been downloaded, so make sure you show some message or some indication to the user to let them know it is doing something

Stephani Bishop
  • 1,261
  • 1
  • 13
  • 20
2

Use download attribute of the link. But it works only in Chrome browser :)

ValeriiVasin
  • 8,628
  • 11
  • 58
  • 78
2

This effect is accomplished by sending an additional header. You can use PHP, for example, to achieve this:

URLs can be rewritten using .htaccess, (internally) redirecting the request to a PHP file. I will show a simple hard-coded example, of how the header can be set:

<?php
    header('Content-type: text/plain');
    header('Content-Disposition: attachment; filename="test001.txt"');
    readfile('files/test.txt');
     //assuming that the files are stored in a directory, not in a database
?>
Rob W
  • 341,306
  • 83
  • 791
  • 678
  • but this does not acomplish the dynamic nature he is looking for. My guess of course – Truesky Sep 15 '11 at 10:28
  • I showed how the headers can be set. If he has the skills to program in PHP, he can alter the code to accomplish his goal. – Rob W Sep 15 '11 at 10:29
0

You can't do that in Javascript. The "Save to"-dialog is openend by the browser and you can't access that through JS, it's a standard-dialog from the OS.

Your server must provide the file with the desired name before the user clicks on the download-link.

What's the reason that you want to rename the downloaded file anyway?

Michael Sandino
  • 1,818
  • 1
  • 13
  • 10
  • I have the files in a Sharepoint library and I'm trying to create a custom action to download the files and add the document version in the file name. To do this custom action I can only use javascript code. Any tips? – bruno2007 Sep 15 '11 at 13:33
0

If what you want is to return a continuous type of file name, you have to write a script that will keep track of that and provide that file back to the user. One way is using plain PHP, or something more advanced if it is several files at a time, possibly a cURL call in php so it can generate several different files. I am guessing that is what you are looking on doing, but you can't have the file name changed dynamically on the save box in that sense, you return the savename.txt filename.

Truesky
  • 221
  • 2
  • 12
0

You can download the file using Fetch API, convert the fetch response into a Blob, create a blob URL from the blob, and then use an anchor with the download attribute (using the desired name) to download the file from the blob URL.

        <Link
            onClick={async() => {
                const url = `https://external-website.com/${file.s3Key}`;
                const downloadedFile = await fetch(url).then(response => {
                    if (response.ok) {
                        return response.blob();
                    }
                    else {
                        errorToast('It was not possible to download the file');
                        return undefined;
                    }
                });
                if (downloadedFile) {
                    const a = document.createElement('a');
                    const downloadUrl = window.URL.createObjectURL(downloadedFile as any);
                    a.href = downloadUrl;
                    a.download = file.filename; // use the name you want
                    a.click();
                }
            }}
            sx={{
                textDecoration: 'none',
                fontSize: 16,
                cursor: 'pointer'
            }}
        >
            Download
        </Link>