Node JS中的文件下载

3

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

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()从未被发送之后,我尝试了以下内容:

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();
    });

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


什么是“解密”? - Zlatan Omerović
我的第一反应猜测是,由于您从未使用“res”关闭请求,因此您的请求挂在系统内存中。 - D Lowther
@omerowitz,我更新了我的问题。 - Alex Turdean
@DLowther 是的,我尝试了几种方法来正确地结束我的请求,但是没有任何效果。 - Alex Turdean
2个回答

1

好的。但是我的文件已经加密了,我必须先解密它。在下载之前我该如何解密它? - Alex Turdean

1

这个错误通常发生在内存不足时。因此,在使用完每个流后,我们必须关闭它。

流是事件发射器,因此您可以监听特定的事件。

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();
})

})

但是如果我这样做,据我所知,我可能会关闭它得太早了。对吗? - Alex Turdean
@AlexTurdean 不确定你所说的“太早”是什么意思?通过在代码中放置语句的位置来决定何时发生。 - Katie.Sun
@Bhuvi 无论如何,我为你尝试了一下,但是出现了内存泄漏检测错误。 - Alex Turdean

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接