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

Buz*_*zut 6 javascript file-upload node.js multer

我有一个节点/express 应用程序,可以使用 multer 处理文件上传。在我的本地计算机上一切正常,但在服务器上,如果上传的文件超过几兆字节,浏览器将停止并出现“连接重置”错误。

\n\n

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

\n\n
var express = require(\'express\');\nvar multer = require(\'multer\');\n\n// Create server\nvar app = express();\n\n// Start server\nfunction startServer() {\n    var port = 8888;\n    server = app.listen(port, function () {\n        console.log(\'Node version:\' + process.versions.node);\n        console.log(\'Express server listening on port %d in %s mode\', port, app.settings.env);\n    });\n}\n\nvar upload = multer({dest: \'./tmp/\'});\n\nvar app = express()\n\napp.post(\'/\', upload.single(\'data\'), function (req, res, next) {\n    console.log(req.file);\n});\n\nstartServer();\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是测试上传的 html 页面:

\n\n
<!doctype html>\n<html>\n    <head>\n        <meta charset="utf-8">\n        <meta http-equiv="x-ua-compatible" content="ie=edge">\n        <title>Test Upload</title>\n        <meta name="description" content="">\n        <meta name="viewport" content="width=device-width, initial-scale=1">\n\n    </head>\n    <body>\n        <p>Hello world! This is a test upload.</p>\n\n        <form method="post" action="http://192.168.1.234:8888" enctype="multipart/form-data">\n            <label>file</label><br>\n            <input type="file" name="data"><br>\n\n            <input type="submit" name="submit" value="Upload">\n        </form>\n\n\n    </body>\n</html>\n
Run Code Online (Sandbox Code Playgroud)\n\n

我在两台不同的服务器 \xe2\x80\x93 上测试了一个 VPS 和一个裸机 \xe2\x80\x93 我最终在两台服务器上都出现了相同的错误。上传开始,我可以在目录中看到文件的一大块./tmp,但它永远不会完成,并且不会在节点或系统日志中抛出任何错误。

\n

Buz*_*zut 5

@NadavL 是对的,尽管我没有前端服务器,但节点本身超时了。

\n\n

文档中写道,节点默认情况下没有超时。Express 可能会覆盖这一点,但我找不到有关此事的任何信息。

\n\n

要全局定义特定超时,您可以通过在服务器连接时更改套接字超时来继续

\n\n
[\xe2\x80\xa6]\n\n// Start server\nfunction startServer() {\n    var port = 8888;\n    server = app.listen(port, function () {\n        console.log(\'Node version:\' + process.versions.node);\n        console.log(\'Express server listening on port %d in %s mode\', port, app.settings.env);\n    });\n\n    server.on(\'connection\', function(socket) {\n        // 10 minutes timeout\n        socket.setTimeout(10 * 60 * 1000);\n    });\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

但是,随着高超时会增加服务器遭受慢速 HTTP 攻击的风险,您可能需要更改特定路由 \xe2\x80\x93 的默认超时,在我的例子中,仅针对上传路由。在这种特殊情况下,您所要做的就是更改路由处理程序中的超时,如下所示:

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

还有一个专用的中间件来处理超时,它称为connect-timeout,它也可用于为不同的路由配置特定的超时(请参阅SO 上的这篇文章)。

\n


Ero*_*rol 5

据我了解我的问题,上传大文件 60 秒后收到 ERR_CONNECTION_RESET。增加请求超时req.setTimeout(value, cb)是不够的。

服务器headersTimeout字段需要手动增加,如下所示:

server.headersTimeout = timeoutValue;
Run Code Online (Sandbox Code Playgroud)

关于 server_headers_timeout 的节点文档

Github问题详细描述了解决方案