node/express Force browser to download file with custom name

10,768

Solution 1

You need to add a new header to the response object to indicate the file name and do a regular download.

res.set("Content-Disposition", "attachment;filename=somefile.ext");

You could also use "inline" if instead you want the browser to try to open the file within it self, like with Chrome does with pdf files.

res.set("Content-Disposition", "inline;filename=somefile.ext");

As per @Thomas suggestion, also is a good idea to include always the right content type:

res.set("Content-Type", "application/octet-stream");

Solution 2

In Express 4 and later, there are 2 helper functions to change the content-type and specify attachment disposition:

res.type("application/octet-stream");
res.attachment("filename.ext");

See docs for type and attachment.

Share:
10,768
vitosorriso
Author by

vitosorriso

Updated on June 12, 2022

Comments

  • vitosorriso
    vitosorriso almost 2 years

    I've built a node/express website for my university project that, after searching for an ID of a law, it shows a big table with all files in different formats and languages related with this id. I use the module "http-proxy" to request and serve these files to client. Nothing wrong when serving xml, xhtml, html and pdf files (every browser is able to directly view them). I have problems with .zip and .rdf files. Files are not corrupted but they are losing the original name

    • when i click on ZIP icon, it gives me the download prompt, but I'm losing the original file name (the file will be called "proxy" or "proxy.zip", different behaviors on different browsers)
    • when i click on RDF icon, some browsers opens the file directly in browser, some browsers won't recognize the format, some browsers wants to download it with name "proxy")

    So I discovered the HTML5 attribute "download" of the tag "a". It just solve my problem, anyway it is not supported on every version of Internet Explorer and Safari. Surfing the web I found some workarounds to add "Right click and save as..." after a div link when the page is viewed in IE or Safari, but this solution is not for me, because i'm not talking about a single link but a table full of links. And my site need to work also on mobile phones.

    Is there any way to write some server-side code to force browsers to download files with a custom file name?

    Here is the small piece of code of the proxy:

    var httpProxy = require('http-proxy');
    var proxy = httpProxy.createProxyServer({ ignorePath: true });
    
    app.get('/proxy', function(req , res) {
        var file = req.query.file;
        var realurl = 'http://'+cfg.edb_opt.host+':'+cfg.edb_opt.port+cfg.edb_opt.rest+file;
        console.log('Proxy: serving '+realurl);
        proxy.web(req, res, { 'target': realurl });
    });
    

    All cfg* variables comes from a json configuration file to set the host, port, and starting path where files are contained.

    Thanks in advance :)

  • Thomas
    Thomas almost 8 years
    to enforce a download, you may want to also add Content-Type: application/octet-stream to Content-Disposition: attachment