http.Server 是一个基于事件的 HTTP 服务器
http.request 则是一个HTTP 客户端工具,用于向 HTTP 服务器发起请求,例如实现Pingback或者内容抓取
http.createServer 创建了一个 http.Server 的实例
//app.js
var http = require('http');
http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.write('<h1>Node.js</h1>');
res.end('<p>Hello World</p>');
}).listen(3000);
console.log("HTTP server is listening at port 3000.");分别是请求对象( req )和响应对象( res )。
在函数体内,res 显式地写回了响应代码 200 (表示请求成功),
指定响应头为'Content-Type': 'text/html',
然后写入响应体 '<h1>Node.js</h1>',
通过 res.end结束并发送。
最后该实例还调用了 listen 函数,启动服务器并监听 3000 端口。
http下的api除了createServer还有server,request等,
用http.server和http.createServer的效果差不多
//httpserver.js
var http = require('http');
var server = new http.Server();
server.on('request', function(req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.write('<h1>Node.js</h1>');
res.end('<p>Hello World</p>');
});
server.listen(3000);
console.log("HTTP server is listening at port 3000."); http.Server 的事件它继承自EventEmitter,并提供以下事件
- request:当客户端请求到来时,该事件被触发,提供两个参数 req 和res,分别是
http.ServerRequest 和 http.ServerResponse 的实例,表示请求和响应信息。
- connection:当 TCP 连接建立时,该事件被触发,提供一个参数 socket,为
net.Socket 的实例。connection 事件的粒度要大于 request,因为客户端在Keep-Alive 模式下可能会在同一个连接内发送多次请求
- close :当服务器关闭时,该事件被触发。注意不是在用户连接断开时。
http.ServerRequest
HTTP 请求一般可以分为两部分:请求头(Request Header)和请求体(Requset Body)
http.ServerRequest主要是控制请求体 ,以下三个事件均用来控制请求体的内容
data:当请求体数据到来时,该事件被触发。该事件提供一个参数 chunk,表示接
收到的数据。如果该事件没有被监听,那么请求体将会被抛弃。该事件可能会被调
用多次。
end :当请求体数据传输完成时,该事件被触发,此后将不会再有数据到来。
close: 用户当前请求结束时,该事件被触发。不同于 end,如果用户强制终止了
传输,也还是调用close。
获取 GET 请求内容
//httpserverrequestget.js
var http = require('http');
var url = require('url');
var util = require('util');
http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end(util.inspect(url.parse(req.url, true)));
}).listen(3000);在浏览器中输入http://127.0.0.1:3000/user?name=byvoid&email=byvoid@byvoid.com
Url {
protocol: null,
slashes: null,
auth: null,
host: null,
port: null,
hostname: null,
hash: null,
search: '?name=byvoid&email=byvoid@byvoid.com',
query:
[Object: null prototype] { name: 'byvoid', email: 'byvoid@byvoid.com' },
pathname: '/user',
path: '/user?name=byvoid&email=byvoid@byvoid.com',
href: '/user?name=byvoid&email=byvoid@byvoid.com'
}url.parse,原始的 path 被解析为一个对象,util.inspect是一个将任意对象转换为字符串,query 就是我们所谓的 GET请求的内容,而路径则是 pathname。
获取 POST 请求内容
POST 请求的内容全部都在请求体中。
http.ServerRequest 并没有一个属性内容为请求体,原因是等待请求体传输可能是
一件耗时的工作,譬如上传文件。而很多时候我们可能并不需要理会请求体的内容,恶意的 POST请求会大大消耗服务器的资源。所以 Node.js 默认是不会解析请求体的,当你需要的时候,需要手动来做.
//httpserverrequestpost.js
var http = require('http');
var querystring = require('querystring');
var util = require('util');
http.createServer(function(req, res) {
var post = '';
req.on('data', function(chunk) {
post += chunk;
});
req.on('end', function() {
post = querystring.parse(post);
res.end(util.inspect(post));
});
}).listen(3000);
上面代码并没有在请求响应函数中向客户端返回信息,而是定义了一个 post 变量,用
于在闭包中暂存请求体的信息。通过 req 的 data 事件监听函数,每当接受到请求体的数据,
就累加到 post 变量中。在 end 事件触发后,通过 querystring.parse 将 post 解析为
真正的 POST 请求格式,然后向客户端返回。
http.ServerResponse
http.ServerResponse 有三个重要的成员函数,用于返回响应头、响应内容以及结束请求
response.writeHead(statusCode, [headers]):向请求的客户端发送响应头。
statusCode 是 HTTP 状态码,如 200 (请求成功)、404 (未找到)等。headers
是一个类似关联数组的对象,表示响应头的每个属性。
该函数在一个请求内最多只能调用一次,如果不调用,则会自动生成一个响应头response.write(data, [encoding]):向请求的客户端发送响应内容。
data 是一个 Buffer 或字符串,表示要发送的内容。
如果 data 是字符串,那么需要指定encoding 来说明它的编码方式,默认是 utf-8。
在 response.end 调用之前,response.write 可以被多次调用。response.end([data], [encoding]):结束响应,告知客户端所有发送已经完
成。当所有要返回的内容发送完毕的时候,该函数 必须 被调用一次。它接受两个可
选参数,意义和 response.write 相同。如果不调用该函数,客户端将永远处于
等待状态。
HTTP 客户端
http 模块提供了两个函数 http.request 和 http.get,功能是作为客户端向 HTTP服务器发起求
http.request(options, callback)发起 HTTP 请求。接受两个参数,option 是一个类似关联数组的对象,表示请求的参数,callback 是请求的回调函数。
callback 传递一个参数,为 http.ClientResponse 的实例
http.request 返回一个 http.ClientRequest 的实例
//httprequest.js
var http = require('http');
var querystring = require('querystring');
var contents = querystring.stringify({
name: 'byvoid',
email: 'byvoid@byvoid.com',
address: 'Zijing 2#, Tsinghua University',
});
var options = {
host: 'www.byvoid.com',
path: '/application/node/post.php',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length' : contents.length
}
};
var req = http.request(options, function(res) {
res.setEncoding('utf8');
res.on('data', function (data) {
console.log(data);
});
});
req.write(contents);
req.end(); http.get(options, callback) 于自动将请求方法设为了 GET 请求,同时不需要手动调用 req.end()。
//httpget.js
var http = require('http');
http.get({host: 'www.byvoid.com'}, function(res) {
res.setEncoding('utf8');
res.on('data', function (data) {
console.log(data);
});
});