Node.js HTTP服务器

> 创建HTTP服务器

var http = require('http');
var server = http.createServer(function(request, reponse){

}).listen('9999','127.0.0.1', function(){
	console.log('开始监听');
});

/////
var server = http.createServer();
server.on('request', function(request, reponse){

});
// listen方法第一参数为端口号,0表示随机端口
// 第三参数默认是511表示最大连接数量
server.listen('9999','127.0.0.1', function(){
	console.log('开始监听');
});
//listen方法将触发listening事件,如果不指定回调
server.on('listening', function(){
	console.log('开始监听');
});

// 显式关闭HTTP服务器,触发close事件,可以监听它做善后处理
server.close()
server.on('close', function(){});

// 如果端口冲突,将触发server的error事件
server.on('error', function(e){
	if(e.code == 'EADDRINUSE') {
	}
});
// 当有客户端连接进来时触发server的connection对象
// 回调参数为服务器端用于监听客户端请求的socket端口对象
server.on('connection', function(socket){
});

方法createServer()的回调中第一参数是http.IncomingMessage对象,此处代表一个客户端请求,第二个参数值为一个http.ServerResponse对象,代表一个服务器端响应对象。

方法createServer方法返回被创建的服务器对象,如果不在createServer方法中使用参数,也可以通过监听该方法创建的服务器对象的request事件(这种方式比较直观)

可以使用HTTP服务器的setTimeout方法来设置服务器的超时时间。当该超时时间超过之后,客户端不可继续利用本次与HTTP服务器建立的连接,下次向该HTTP服务器发出请求时必须重新建立连接

// 设置超时并给出超时时需要执行的回调
server.setTimeout(1000, function(socket) {
});
// 超时时会触发timeout事件 
server.on('timeout', function(socket){

});
// 也可以直接操作server的timeout属性
server.timeout = 1000;
console.log(server.timeout);

HTTP服务器拥有一个timeout属性,属性值为整数值,单位为毫秒,可用于查看或修改服务器的超时时间。

> 获取客户端请求信息
http.IncomingMessage用于读取客户端请求流中的数据,当从客户端请求流中读取到新的数据时触发data事件,当读取完客户端请求流中的数据时触发end事件。当该对象被用于读取客户端请求流中的数据时,有如下属性:

.method		GET POST PUT DELETE
.url		带请求查询的URL
.headers	客户端发送的请求头
.httpVersion
.trailers	客户端附加的HTTP头(end事件触发后才能读取)
.socket		socket对象

例子:

var http = require('http');

var server = http.createServer(function (req, res) {
	 //console.log(req);
	 console.log(req.method);
	 console.log(req.url);
	 console.log(req.headers);
	 // data触发主要用来接收客户端请求体的数据,比如POST的数据
	 req.on('data', function(data) {
		console.log(decodeURIComponent(data));
	 });

	 req.on('end', function(){
		console.log("客户端数据已经全部接收");
	 });
}).listen(9999, '127.0.0.1');

server.on('connection',function(socket){
	console.log('客户端连接已建立');
});

> 转换URL字符串与查询字符串
在Node.js中,提供了一个url模块与一个queryString模块,分别用来转换完整URL字符串与URL中的查询字符串。

querystring.parse('userName=Lulingniu&age=40&sex=male','&','=');
querystring.stringify({username:'vfeelit',age:'18',sex:'male'})
// 第二参数表示是否解析查询字符串为一个对象
// 内部实际使用querystring对象
url.parse('http:// user:pass@host.com:8080/users/user.php?userName=vv&age=18&sex=male#name1')
url.format(urlObj);
url.resolve(from, to); //可以简单看做是字符串替换

> 发送服务器响应
利用http.ServerResponse对象的writeHead方法来发送响应头

var http = require('http');
var server = http.createServer(function(req, res){
	res.writeHead(200, {'Content-Type':'text/plain', 'Access-Control-Allow-Origin':'http://127.0.0.1'});
	//也可以使用setHeader设置响应头 
	res.setHeader("Set-Cookie",["type=xx","language=xxxx"]);
	res.write("Hello");
	res.end();
});

使用了http.ServerResponse对象的setHeader方法设置响应头信息之后,可以使用http.ServerResponse对象的getHeader方法获取响应头中的某个字段值。使用http.ServerResponse对象的removeHeader方法删除一个响应字段。http.ServerResponse对象具有一个headersSent属性,当响应头已发送时,该属性值为true,当响应头未发送时,属性值为false。

HTTP服务器自动将服务器端当前时间作为响应头中的Date字段值发送给客户端。可以通过将http.ServerResponse对象的sendDate属性值设置为false的方法在响应头中删除Date字段。

可以通过http.ServerResponse对象的statusCode属性值获取或设置HTTP服务器返回的状态码。

可以使用http.ServerResponse对象的setTimeout方法设置响应超时时间。如果在指定时间内服务器没有做出响应,则响应超时,同时触发http.ServerResponse对象的timeout事件。

在http.ServerResponse对象的end方法被调用之前,如果连接中断,将触发http.ServerResponse对象的close事件。

> HTTP客户端
request方法返回一个http.ClientRequest对象,代表一个客户端请求。

当客户端请求获取到服务器响应流时,触发http.ClientRequest对象的response事件,可以不在request方法中使用callback参数,而是通过对http.ClientRequest对象的response事件进行监听并指定事件回调函数的方法来指定当获取到其他网站返回的响应流时执行的处理。

var http = require('http');
var option = {
	hostname: 'blog.ifeeline.com',
	port:80,
	path:'/',
	method:'GET'
};
//回调在reponse事件触发时执行
var req = http.request(options, function(res){
});
// http.request()方法返回一个http.clientRequest对象,调用end()方法将发起请求
// 数据返回后触发reponse事件,所以可以如下
req.on('reponse', function(res){
});
// res对象是一个http.IncomingMessage对象,表示发起请求的响应

// 可以调用http.clientRequest对象的write来发送数据,比如上次文件
// 这些内容实际就是HTTP请求中的请求体
req.write(chunk,[encoding])
// 必须调用end方法来结束请求(实际是发出请求)
// end中的参数(可空),类似最后执行一次write方法
req.end([chunk],[encoding])

使用http.ClientRequest对象的abort方法终止本次请求,如果在向目标网站请求数据的过程中发生了错误,将触发http.ClientRequest对象的error事件。在建立连接的过程中,当为该连接分配端口时,触发http.ClientRequest对象的socket事件。

如果使用GET方式向其他网站请求数据,也可以使用http模块中的get方法。