Node.js 使用 multer 上传文件时连接重置
Node.js connection reset on file upload with multer
我有一个 node/express 应用程序可以使用 multer 处理文件上传。在我的本地机器上一切正常,但在服务器上,如果上传的文件超过几 Mb,浏览器将停止并显示 "connection reset" 错误。
这是上传脚本的简单测试版本:
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
目录中看到一个文件块,但它永远不会完成,也不会抛出任何错误,无论是在节点中还是在系统日志中。
@NadavL 是对的,尽管事实上我没有前端服务器,但节点本身正在超时。
the docs里面写到node默认是没有timeout的。 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);
});
}
但是随着超时时间过长会增加您的服务器对 Slow HTTP Attacks 的暴露程度,您可能想要更改特定路由的默认超时时间——在我的例子中,只是针对上传路由。在这种特殊情况下,您所要做的就是像这样更改路由处理程序中的超时:
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 and it can be used to configure specific timeouts for different routes too (see this post on SO)。
据我了解我的问题,上传大文件 60 秒后收到 ERR_CONNECTION_RESET。使用 req.setTimeout(value, cb)
增加请求超时是不够的。
服务器headersTimeout
字段需要手动增加如下:
server.headersTimeout = timeoutValue;
我有一个 node/express 应用程序可以使用 multer 处理文件上传。在我的本地机器上一切正常,但在服务器上,如果上传的文件超过几 Mb,浏览器将停止并显示 "connection reset" 错误。
这是上传脚本的简单测试版本:
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
目录中看到一个文件块,但它永远不会完成,也不会抛出任何错误,无论是在节点中还是在系统日志中。
@NadavL 是对的,尽管事实上我没有前端服务器,但节点本身正在超时。
the docs里面写到node默认是没有timeout的。 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);
});
}
但是随着超时时间过长会增加您的服务器对 Slow HTTP Attacks 的暴露程度,您可能想要更改特定路由的默认超时时间——在我的例子中,只是针对上传路由。在这种特殊情况下,您所要做的就是像这样更改路由处理程序中的超时:
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 and it can be used to configure specific timeouts for different routes too (see this post on SO)。
据我了解我的问题,上传大文件 60 秒后收到 ERR_CONNECTION_RESET。使用 req.setTimeout(value, cb)
增加请求超时是不够的。
服务器headersTimeout
字段需要手动增加如下:
server.headersTimeout = timeoutValue;