2012-05-31 28 views
4

我有一些错误,当使用http.request做客户端请求(节点v0.6.18,v0.6.3),下面的代码产生的错误,我有一些问题。nodejs错误:解析错误在Socket.ondata

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. 为什么资源的 '结束' 事件早于插座的 '错误' 的事件发生?
  2. 如果我确实想回调一个错误,当“解析错误在Socket.ondata”发生像上面的代码或在任何其他情况下,如何回调一次,而不是上述输出的两倍(IF res的'结束'事件真的比套接字的'错误'事件早发生)?

我需要你的帮助!谢谢。

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

我发现相同的代码输出:

res on end 
result, err: null, data: � 

在节点v0.6.6和v0.6.11中。为什么?

+0

心灵?我不记得在野外看到一个不正确的内容长度标题。 –

+0

为什么不修复内容长度标题,然后尝试 – Esailija

+0

@Nathan Friedly,Esailija,我不知道为什么错误“错误:解析错误 在Socket.ondata(http.js:1124:24)在TCP.onread(net.js:348:27)处出现“ ”实际上(当然我想知道这是怎么发生的,并且进程总是会突然停止,并且出现这个异常),我发现这是从google重现它的一种方式。 – Boris

回答

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(); 

(我试过之后的所有新生产线的补充意见,使他们脱颖而出一点。)如果我问为什么这对你很重要

+0

感谢您的回答。你知道为什么输出在节点(0.6.18或0.6.3)和(0.6.6和0.6.11)之间有不同的行为吗? – Boris

+0

我认为这可能是一个引入并修复的错误(套接字在发生错误数据时应该会发出错误)。 –

+0

我在这里发布一个问题:[链接](https://github.com/joyent/node/issues/3354)。我应该安装侦听器的套接字对象? – Boris