nodejs错误:Socket.ondata中的解析错误

时间:2012-05-31 17:14:08

标签: javascript http sockets node.js

使用http.request发出客户端请求时出现错误(节点v0.6.18,v0.6.3),以下代码产生错误,我有一些问题。

var http = require('http');
var url = require('url');

http.createServer(function(req, res) {
    var data = '多情自古空余恨';
    res.writeHead(200, {
        'Content-Type': 'text/plain',
        'Content-Length': 1 //ERROR
    });
    res.end(data);
}).listen(3000);

function request(options, callback) {
    var req = http.request(options, function(res) {
        var data = '';
        res.setEncoding = 'utf8';
        res.on('data', function(chunk) {
            data += chunk;
        });
        res.on('error', function(err) {
            callback(new Error('res error: ' + err));
        });
        res.on('end', function() {
            console.log('res on end');
            callback(null, data);
        });
    });
    req.on('socket', function(socket) {
        socket.on('error', function(err) {
            console.log('socket on error');
            callback('socket error: ' + err);
            req.abort();
        });
    });
    req.end();
}

request({
    host: 'localhost',
    port: 3000,
    method: 'GET'
}, function(err, data) {
    console.log('result, err: ' + err + ', data: ' + data);
});

输出:

res on end
result, err: null, data: �
socket on error
result, err: socket error: Error: Parse Error, data: undefined

以下是我的问题:

  1. 为什么res的'end'事件发生在socket的'error'事件之前?
  2. 如果我确实想要在“Socket.ondata上的分析错误”发生时回复错误,就像上面的代码或任何其他情况一样,如何回调一次而不是两次作为上面的输出(IF res的'end'事件真的比socket的'错误'事件更早出现了吗?
  3. 我需要你的帮助!感谢。

    ===============================

    我找到了相同的代码输出:

    res on end
    result, err: null, data: �
    
    节点v0.6.6和v0.6.11中的

    。为什么呢?

1 个答案:

答案 0 :(得分:2)

因为内容长度标头为1,所以当request收到恰好1个八位字节的数据时,它会假定全部存在,并触发end回调。之后,接收到更多数据,套接字不知道该怎么做,因此它会触发错误。

要解决此问题,您可能需要等待一小段时间才能触发成功回调并跟踪它是否已被触发。例如:

var req = http.request(options, function(res) {

    var data = '';
    res.setEncoding = 'utf8';
    res.on('data', function(chunk) {
        data += chunk;
    });
    res.on('error', function(err) {
        if(!callback.called) { // check before firing the callback
          callback(new Error('res error: ' + err));
          callback.called = true; // set after firing the callback
        } // ..
    });
    res.on('end', function() {
        process.nextTick(function() { // use setTimeout if nextTick is too short
          if(!callback.called) { //..
            console.log('res on end');
            callback(null, data);
            callback.called = true; // ..
          } // ..
        }); // ..
    });
});
req.on('socket', function(socket) {
    socket.on('error', function(err) {
        if(!callback.called) { // ..
          console.log('socket on error');
          callback('socket error: ' + err);
          callback.called = true; // ..
        } // ..
        req.abort();
    });
});
req.end();

(我尝试在所有新行之后添加注释,以使它们脱颖而出。)