node的http模块

node中的几个常用核心模块的api返回的都是eventEmitter的实例,也就是说都继承了on和emit方法,用以监听事件并触发回调来处理事件。

http模块处理网络请求通常是创建一个server实例:

1 const server = http.createServer((request, response) => {
2 // magic happens here!
3 });

它是以下代码的简写:

1 const server = http.createServer();
2 server.on('request', (request, response) => {
3   // the same kind of magic happens here!
4 });

其中request和response是传入回调的参数,他们是包含了处理请求所需的属性和方法的对象,便于我们完成操作。

request是一个http.IncomingMessage类的实例,带有 Readable Stream接口(方便我们操作流数据),常用的属性有.headers[Obj]、.url[str]、.method[str]

1 const { method, url,headers  } = request;

详见:https://nodejs.org/api/http.html#http_class_http_incomingmessage

当遇到POST或PUT的请求时,我们需要获取报文实体主体的数据,既然request带有Readable Stream接口,我们可以调用这个api获取:

 1 const http = require('http');
 2 
 3 http.createServer((request, response) => {
 4   const { headers, method, url } = request;
 5   let body = [];
 6   request.on('error', (err) => {
 7     console.error(err);
 8   }).on('data', (chunk) => {
 9     body.push(chunk);
10   }).on('end', () => {
11     body = Buffer.concat(body).toString();
12     // At this point, we have the headers, method, url and body, and can now
13     // do whatever we need to in order to respond to this request.
14   });
15 }).listen(8080); // Activates this server, listening on port 8080.

response是一个http.ServerResponse实例,也是一个WritableStream实例。带有方便我们设置响应头和响应主体的api。

response.statusCode = 404;
1 response.setHeader('Content-Type', 'application/json');
2 response.setHeader('X-Powered-By', 'bacon');

也可以一次性完成上面代码:

1 response.writeHead(200, {
2   'Content-Type': 'application/json',
3   'X-Powered-By': 'bacon'
4 });

官方文档强调要先写好响应头的statusCode和headers再写主体,毕竟响应头比响应主体先到达。

1 response.write('<html>');
2 response.write('<body>');
3 response.write('<h1>Hello, World!</h1>');
4 response.write('</body>');
5 response.write('</html>');
6 response.end();

上面的write是WritableStream的api方便我们写响应主体,当然也可以直接写在end()里面:

1 response.end('<html><body><h1>Hello, World!</h1></body></html>');

在官方文档中给过一个echo例子,将request的内容通过pipe()方法尽数写入response作为响应。

1 http.createServer((request, response) => {
2   if (request.method === 'GET' && request.url === '/echo') {
3     request.pipe(response);
4   } else {
5     response.statusCode = 404;
6     response.end();
7   }
8 }).listen(8080);

这里,ReadableStream的pipe()方法在写入完成后,会触发它自身的end事件,然后默认地调用Writablestream的end()方法,即相当于自动调用了response.end();另外,pipe()方法也会返回对目标writerable的引用,便于链式调用。https://nodejs.org/api/stream.html#stream_class_stream_writable

原文地址:https://www.cnblogs.com/alan2kat/p/7423744.html