在Node JS中下载文件

时间:2018-11-13 11:46:20

标签: javascript node.js download

我正在尝试为nodejs应用实现下载路由器。几次下载后,我的应用程序崩溃了。有什么建议吗?

app.route( "/download" )
.get( (req, res) => {
    var filename = req.query.filename;
    var file = __dirname + '/upload/' + filename;
    var mimetype = mime.lookup(file);

    res.setHeader('Content-disposition', 'attachment; filename=' + req.query.filename);
    res.setHeader('Content-type', mimetype);

    var filestream = fs.createReadStream(file);
    filestream.pipe(decrypt).pipe(res);

})

我收到此错误:

    Error [ERR_STREAM_WRITE_AFTER_END]: write after end
at writeAfterEnd (_stream_writable.js:243:12)
at Decipher.Writable.write (_stream_writable.js:291:5)
at ReadStream.ondata (_stream_readable.js:666:20)
at ReadStream.emit (events.js:182:13)
at addChunk (_stream_readable.js:283:12)
at readableAddChunk (_stream_readable.js:264:11)
at ReadStream.Readable.push (_stream_readable.js:219:10)
at fs.read (internal/fs/streams.js:196:12)
at FSReqCallback.wrapper [as oncomplete] (fs.js:473:5)
    Emitted 'error' event at:
at Decipher.onerror (_stream_readable.js:690:12)
at Decipher.emit (events.js:182:13)
at writeAfterEnd (_stream_writable.js:245:10)
at Decipher.Writable.write (_stream_writable.js:291:5)
[... lines matching original stack trace ...]
at FSReqCallback.wrapper [as oncomplete] (fs.js:473:5)

更新 有人问解密,文件使用加密模块加密:

var decrypt = crypto.createDecipher(algorithm, password);

此外,在阅读res.end() is never sent after streaming a file to client之后,我尝试了以下方法:

var filestream = fs.createReadStream(file);
    filestream.pipe(decrypt).pipe(res, {end: false});
    filestream.on("close", function() {
        res.status(200);
        res.end();
    });
    filestream.on("error", function() {
        res.status(400);
        res.end();
    });

它不起作用:(,我收到相同的错误

2 个答案:

答案 0 :(得分:0)

只需使用res.download(<filepath>)

https://expressjs.com/en/api.html#res.download

答案 1 :(得分:0)

当我们的内存不足时,通常会发生此错误。 因此,我们必须在使用每个流之后将其关闭。

流是EventEmitter,因此您可以侦听某些事件。

app.route( "/download" ).get( (req, res) => {
var filename = req.query.filename;
var file = __dirname + '/upload/' + filename;
var mimetype = mime.lookup(file);

res.setHeader('Content-disposition', 'attachment; filename=' + req.query.filename);
res.setHeader('Content-type', mimetype);

var filestream = fs.createReadStream(file);
filestream.pipe(decrypt).pipe(res);
filestream.on("finish", function(){
  res.send();
})

})