var http=require('http');
var qs=require('querystring');
var post_data={a:123,time:new Date().getTime()};//这是需要提交的数据
var content=qs.stringify(post_data);
var options = {
host: 'localhost',
port: 3000,
path: '/',
method: 'POST',
headers:{
'Content-Type':'application/x-www-form-urlencoded',
'Content-Length':content.length
}
};
console.log("post options:\n",options);
console.log("content:",content);
console.log("\n");
var req = http.request(options, function(res) {
console.log("statusCode: ", res.statusCode);
console.log("headers: ", res.headers);
var _data='';
res.on('data', function(chunk){
_data += chunk;
console.log(_data);
});
res.on('end', function(){
//data = qs.parse(_data);
console.log('end is emitted');
console.log("\n--->>\nresult:",_data)
});
});
req.write(content);
req.end();
//服务器
var http = require('http');
var url = require('url');
var util = require('util');
var qs = require('querystring');
http.createServer(function(req,res){
var data = '';
req.on('data',function(chunk){
data+=chunk;
});
req.on('end',function(){
res.writeHead(200, {
'Content-Length': data.length,
'Content-Type': 'text/plain' });
data = qs.parse(data);
console.log(data.a.toString());
res.write(data.a.toString());
res.end('hello');
//data = qs.parse(data);
console.log(data);
});
}).listen(3000);
console.log("!!!");
在客户端 我的res.on(end)事件始终没有反应……这是为什么?
哥哥,你的req.end()调用的时候服务器还没启动呢?我给你的代码稍微改了下. req.write(content);req.end();放到.listen(3000);的回调函数里面得到了你想要的结果.
listen(3000,function(){
req.write(content);
req.end();
});
经过哥的深入分析,原来是这里的问题:
res.writeHead(200, {
'Content-Length': data.length, // 应该去掉这一行
'Content-Type': 'text/plain' });
一般情况下是不需要自己去手动设置这个 Content-Length
的,但是你奇葩地去做了;
如果你没有设置 Contebt-Length
,http模块内部是会自动帮你计算的,但是你设置了这个值,而你实际返回的数据长度却没有这么多,于是http客户端请求时就在那傻傻地等(即使你已经 res.end()
了),直到连接关闭后才触发 end
事件。
设置了不正确的 Content-Length
的后果就是,如果实际数据长度超过了这个值,后面会被截断,如果实际没有这么大,就形成了 “无法触发end事件” 的假象。
是Content-Length的問題沒錯
參照:
http://nodejs.org/api/http.html#http_response_writehead_statuscode_reasonphrase_headers
Note: that Content-Length is given in bytes not characters. The above example works because the string 'hello world' contains only single byte characters. If the body contains higher coded characters then Buffer.byteLength() should be used to determine the number of bytes in a given encoding. And Node does not check whether Content-Length and the length of the body which has been transmitted are equal or not.
@dengqiao 长度对个毛啊
res.writeHead(200, {
'Content-Length': data.length, // 这里的data是客户端提交上来的数据,内容大概为 {"a":123,"time":1373443826951}
'Content-Type': 'text/plain' });
data = qs.parse(data);
console.log(data.a.toString());
res.write(data.a.toString()); // 这里的内容是 123
res.end('hello'); // 这里的内容是 hello
// 两个加起来的话就是 123hello
而你在评论中给出的例子:
listen(3000,function(){
req.write(content);
req.end();
});
写得如此马虎, req
变量从哪里的? 有 req.end()
的么?
你这代码的运行结果是你口算出来的吧?!
@dengqiao 我肯定你没好好看我的评论:
如果 data
是 "a=123&time=1373444684836", data.length
的值为 24
服务器返回的内容是 "123hello", 其长度为 8
@ggaaooppeenngg 在这个例子中,你执行 res.writeHead()
都是多余的:默认响应的statusCode就是200,Content-Lenght是自动计算的,Content-Type是text/plain
@leizongmin @snoopy @hankwang 跟我设想的一样,0.10.12版本可以运行成功的原因是客户端header中没有Connection: 'keep-alive’服务器在服务完请求后会关闭connection,这样在0.10.12版本中触发了end事件,这个应该是node在后续中的一个改进,我在楼主的代码中加上Connection: 'keep-alive’在0.10.12版本中就无法触发end事件了.