Node.js使用multer上传文件时连接重置

5

我有一个使用multer处理文件上传的node/express应用程序。在我的本地机器上一切运作良好,但在服务器上,如果上传的文件超过几MB,浏览器会因为“连接重置”错误而停止。

这里是上传脚本的简单测试版本:

var express = require('express');
var multer = require('multer');

// Create server
var app = express();

// Start server
function startServer() {
    var port = 8888;
    server = app.listen(port, function () {
        console.log('Node version:' + process.versions.node);
        console.log('Express server listening on port %d in %s mode', port, app.settings.env);
    });
}

var upload = multer({dest: './tmp/'});

var app = express()

app.post('/', upload.single('data'), function (req, res, next) {
    console.log(req.file);
});

startServer();

这里是用于测试上传的HTML页面:

<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <title>Test Upload</title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">

    </head>
    <body>
        <p>Hello world! This is a test upload.</p>

        <form method="post" action="http://192.168.1.234:8888" enctype="multipart/form-data">
            <label>file</label><br>
            <input type="file" name="data"><br>

            <input type="submit" name="submit" value="Upload">
        </form>


    </body>
</html>

我在两个不同的服务器上进行了测试——一个是虚拟专用服务器(VPS),另一个是裸金属机器——结果两个服务器都出现了同样的错误。上传开始后,我可以在我的./tmp目录下看到文件的一部分,但是上传从来没有完成,也没有在node或syslog中抛出任何错误。


2
根据我的经验,可能是Apache / Nginx / 你的服务器运行的其他任何东西中的超时配置问题,我建议你尝试查看一下这方面的设置。 - NadavL
可能剩余的磁盘空间不够了? - Medet Tleukabiluly
@NadavL 到目前为止,Node 是前端服务器,没有任何代理到它... - Buzut
@MedetTleukabiluly 在一个服务器上还剩下几个G的空间,在另一个服务器上还剩下几百个G,所以我不认为这是问题的根源。 - Buzut
2个回答

5

@NadavL是正确的,尽管我没有前端服务器,但node自己会超时。

文档中写道,默认情况下node没有超时。Express可能会覆盖此设置,但我找不到任何相关信息。

要全局定义特定的超时时间,可以在服务器连接时更改套接字超时时间。

[…]

// Start server
function startServer() {
    var port = 8888;
    server = app.listen(port, function () {
        console.log('Node version:' + process.versions.node);
        console.log('Express server listening on port %d in %s mode', port, app.settings.env);
    });

    server.on('connection', function(socket) {
        // 10 minutes timeout
        socket.setTimeout(10 * 60 * 1000);
    });
}

但是,随着超时时间的增加,您的服务器更容易受到慢速HTTP攻击的影响,您可能希望仅针对特定路由(在我的情况下,仅针对上传路由)更改默认超时时间。在这种特殊情况下,您只需要像以下方式更改路由处理程序中的超时时间:

app.post('/myroute', function (req, res) {
    // 10 minutes timeout just for POST to myroute
    req.socket.setTimeout(10 * 60 * 1000);
    upload.single('data');
    console.log(req.file);
});

还有一个专门处理超时的中间件,它被称为connect-timeout,可以用于为不同的路由配置特定的超时时间(请参见此篇关于SO的文章)。


3

1
我花了超过8个小时来解决这个问题,但这个答案为我节省了数十个小时。谢谢。 - kitsoRik

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