node.js在发出http请求时区分错误
Posted
技术标签:
【中文标题】node.js在发出http请求时区分错误【英文标题】:node.js distinguishing errors when making http request 【发布时间】:2013-10-19 18:37:53 【问题描述】:我的 node.js 应用程序正在使用 http.request
到 REST API http://army.gov/launch-nukes
,我需要区分三种可能的情况:
Success
-- 服务器回复是肯定的。我知道我的敌人已经被消灭了。
Failure
-- 我收到了来自服务器的错误,或者无法连接到服务器。我还有敌人。
Unknown
-- 与服务器建立连接后,我已经发送了请求 -- 但不确定发生了什么。这可能意味着该请求从未发送到服务器,或者服务器对我的响应从未发送过。我可能刚刚开始了一场世界大战,也可能没有。
如您所见,区分Failure
和Unknown
案例对我来说非常重要,因为它们的后果和我需要采取的行动不同。
我也非常想使用 http Keep-Alive——我能说什么,我是一个好战分子,并计划在突发事件中发出大量请求(然后在很长一段时间内什么都没有)时间)
--
问题的核心是如何将连接错误/超时(这是一个Failure
)与在请求上线后发生的错误/超时(这是一个Unknown
)。
在伪代码逻辑中我想要这个:
var tcp = openConnectionTo('army.gov') // start a new connection, or get an kept-alive one
tcp.on('error', FAILURE_CASE);
tcp.on('connectionEstablished', function (connection)
var req = connection.httpGetRequest('launch-nukes');
req.on('timeout', UNKNOWN_CASE);
req.on('response', /* read server response and decide FAILURE OR SUCCESS */);
)
【问题讨论】:
能否提供请求的代码? 目前,它是标准的http.request
,但不区分Failure
和Unknown
我的建议是:不要使用 HTTP 请求来发射核导弹。
@GregRos 或者至少请不要使用 GET 请求
【参考方案1】:
这是一个例子:
var http = require('http');
var options =
hostname: 'localhost',
port: 7777,
path: '/',
method: 'GET'
;
var req = http.request(options, function (res)
// check the returned response code
if (('' + res.statusCode).match(/^2\d\d$/))
// Request handled, happy
else if (('' + res.statusCode).match(/^5\d\d$/))
// Server error, I have no idea what happend in the backend
// but server at least returned correctly (in a HTTP protocol
// sense) formatted response
);
req.on('error', function (e)
// General error, i.e.
// - ECONNRESET - server closed the socket unexpectedly
// - ECONNREFUSED - server did not listen
// - HPE_INVALID_VERSION
// - HPE_INVALID_STATUS
// - ... (other HPE_* codes) - server returned garbage
console.log(e);
);
req.on('timeout', function ()
// Timeout happend. Server received request, but not handled it
// (i.e. doesn't send any response or it took to long).
// You don't know what happend.
// It will emit 'error' message as well (with ECONNRESET code).
console.log('timeout');
req.abort();
);
req.setTimeout(5000);
req.end();
我建议你使用netcat来玩它,即:
$ nc -l 7777
// Just listens and does not send any response (i.e. timeout)
$ echo -e "HTTP/1.1 200 OK\n\n" | nc -l 7777
// HTTP 200 OK
$ echo -e "HTTP/1.1 500 Internal\n\n" | nc -l 7777
// HTTP 500
(等等……)
【讨论】:
在我拥有的netcat
版本(0.7.1
和1.10-39
)中,我不得不改用以下命令(添加-p
):nc -l -p 7777
不应该req.statusCode
是res.statusCode
?以上是关于node.js在发出http请求时区分错误的主要内容,如果未能解决你的问题,请参考以下文章
如何从Google Cloud Function(Cheerio,Node.js)发出多个http请求
node.js http.get 在向远程站点发出 5 次请求后挂起