简体   繁体   中英

Download a file from NodeJS Server using hapi

I want to create a file download API using hapi. Without using res.download() , how to do it using reply() ?

You can also download a file from stream

const { Readable } = require('stream');

handler: async (request: any, h: Hapi.ResponseToolkit) => {
  let stream = Fs.createReadStream(filePath);
  let streamData = new Readable().wrap(stream);
  return h.response(streamData)
    .header('Content-Type', contentType)
    .header('Content-Disposition', 'attachment; filename= ' + fileName);
}

To get content type of file you can refer:

getContentType(fileExt) {
        let contentType;
        switch (fileExt) {
            case 'pdf':
                contentType = 'application/pdf';
                break;
            case 'ppt':
                contentType = 'application/vnd.ms-powerpoint';
                break;
            case 'pptx':
                contentType = 'application/vnd.openxmlformats-officedocument.preplyentationml.preplyentation';
                break;
            case 'xls':
                contentType = 'application/vnd.ms-excel';
                break;
            case 'xlsx':
                contentType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
                break;
            case 'doc':
                contentType = 'application/msword';
                break;
            case 'docx':
                contentType = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
                break;
            case 'csv':
                contentType = 'application/octet-stream';
                break;
            case 'xml':
                contentType = 'application/xml';
                break;
        }
        return contentType;
    }

you need to make a Buffer and then set the header and the encoding for the reply

let buf = new Buffer(xls, 'binary');

return reply(buf)
    .encoding('binary')
    .type('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
    .header('content-disposition', `attachment; filename=test-${new Date().toISOString()}.xlsx;`);

This solution is valid for hapi v17 and newer

You may use @hapi/inert module for downloading a file.

First, register the plugin with your server.
await server.register(require("@hapi/inert"));

Then in the handler

downloadFile: function (request, h) {
    
    return h.file("name-of-file-to-download-from-local-system", {
        mode: "attachment",
        filename: "name-to-be-given-to-downloaded-file",
        confine: "/path/to/file/", //This is optional. provide only if the file is saved in a different location
    });

},

Detailed documentation is available here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM