Node.js POST 导致 [错误:套接字挂断] 代码:'ECONNRESET'
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18692580/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Node.js POST causes [Error: socket hang up] code: 'ECONNRESET'
提问by Nam Nguyen
I created a sample to post data to a rest services and I found out that when I have non-ascii or non-latin character (please see data.firstName), my post request using TEST-REST.js will throw
我创建了一个示例将数据发布到休息服务,我发现当我有非 ascii 或非拉丁字符(请参阅 data.firstName)时,我使用 TEST-REST.js 的发布请求将抛出
error: { [Error: socket hang up] code: 'ECONNRESET' }.
错误:{[错误:套接字挂断]代码:'ECONNRESET'}。
// TEST-REST.js
var http = require('http');
var data = JSON.stringify({
firstName: 'Joaquìn',
});
var options = {
host: '127.0.0.1',
port: 3000,
path: '/users',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': data.length
}
};
var req = http.request(options, function(res) {
var result = '';
res.on('data', function(chunk) {
result += chunk;
});
res.on('end', function() {
console.log(result);
});
});
req.on('error', function(err) {
console.log(err);
});
req.write(data);
req.end();
and on my rest services, it throw me error like this:
在我的休息服务中,它抛出了这样的错误:
SyntaxError: Unexpected end of input Sun Sep 08 2013 23:25:02 GMT-0700 (PDT) - at Object.parse (native)
at IncomingMessage.<anonymous> (/Volumes/Data/Program_Data/GitHub/app/node_modules/express/node_modules/connect/lib/middleware/json.js:66:27) info at IncomingMessage.EventEmitter.emit (events.js:92:17)
at _stream_readable.js:920:16 : - - - [Mon, 09 Sep 2013 06:25:02 GMT] "POST /users HTTP/1.1" 400 - "-" "-"
at process._tickDomainCallback (node.js:459:13)
if I replace firstName value from 'Joaquìn' to 'abc', everything works just fine. I think I'm missing something to support or escape to make it work.
如果我将 firstName 值从 'Joaquìn' 替换为 'abc',一切正常。我想我缺少一些东西来支持或逃避以使其工作。
does anyone have any idea how I solve this problem? I also tried following: require('querystring').escape(model.givenName), and it works but I'm not happy with it.
有谁知道我如何解决这个问题?我还尝试了以下操作:require('querystring').escape(model.givenName),它可以工作,但我不满意。
UPDATEDI found out that if I comment out: app.use(express.bodyParser());, the error disappears.
更新我发现如果我注释掉:app.use(express.bodyParser());,错误就会消失。
回答by Nam Nguyen
This is node's issue, not express's issue. https://github.com/visionmedia/express/issues/1749
这是节点的问题,而不是快递的问题。https://github.com/visionmedia/express/issues/1749
to resolve, change from
解决,从
'Content-Length': data.length
'内容长度':data.length
to
到
'Content-Length': Buffer.byteLength(data)
'内容长度':Buffer.byteLength(data)
RULE OF THUMB
经验法则
Always use Buffer.byteLength()when you want to find the content length of strings
当您想查找字符串的内容长度时,请始终使用Buffer.byteLength()
UPDATED
更新
We also should handle error gracefully on server side to prevent crashing by adding middleware to handle it.
我们还应该在服务器端优雅地处理错误,以通过添加中间件来处理它来防止崩溃。
app.use(function (error, req, res, next) {
if (!error) {
next();
} else {
console.error(error.stack);
res.send(500);
}
});
回答by Eric Elliott
The problem is that if you don't handle this error and keep the server alive, this remote crash exploit could be used for a DOS attack. However, you can handle it and continue on, and still shut down the process when unhandled exceptions occur (which prevents you from running in undefined state -- a very bad thing).
问题是,如果您不处理此错误并使服务器保持活动状态,则此远程崩溃漏洞可能会被用于 DOS 攻击。但是,您可以处理它并继续,并且在发生未处理的异常时仍然关闭进程(这会阻止您在未定义状态下运行——这是一件非常糟糕的事情)。
The connect module handles the error and calls next(), sending back an object with the message body and status = 400. In your server code, you can add this after express.bodyParser():
连接模块处理错误并调用next(),将带有消息体和 的对象发回status = 400。在您的服务器代码中,您可以在以下内容之后添加express.bodyParser():
var exit = function exit() {
setTimeout(function () {
process.exit(1);
}, 0);
};
app.use(function (error, req, res, next) {
if (error.status === 400) {
log.info(error.body);
return res.send(400);
}
log.error(error);
exit();
});

