nodejs学习笔记——http事务剖析

前言

翻译整理原文主要内容(非单纯翻译)
原文的目的是让读者对Node.js http处理过程有一个清楚的理解。如果对HTTP请求如何工作、nodejs的事件处理和流不太熟悉,建议先去大致了解。


创建服务

const server = http.createServer();
server.on('request', (request, response) => {
  // server对象其实是一个EventEmitter
  // 绑定事件,对request事件作处理
});

基础代码如上,引入http模块通过createServer方法创建一个网络服务object,其内部传入方法为每次请求都会调用的请求handler。

const { method, url, headers } = request;
const userAgent = headers['user-agent'];

当我们处理request请求时,需要根据方法method、请求路径url做出相应的处理,或者是需要请求头做相应的操作,都可以在request中取到。request对象即为IncomingMessage的实例。
备注:所有请求头信息都为小写传输无视用户实际如何发送,这样简化了请求头解析工作。重复的头信息可能会被覆盖或者整合到一起用分隔符分割。


Request

关于request body请求体

当发送POST、PUT请求时,请求对象被传入Readable流对象处理,我们可以对其进行流对象操作,例如通过监听data和end事件获取其内容。

let body = [];
request.on('data', (chunk) => {
  body.push(chunk);
}).on('end', () => {
  body = Buffer.concat(body).toString();
  // body在这里包含了整个请求体且作为字符串形式存在
});

这一步可能有些乏味,通常交给npm上的模块工具去完成(例如concat-streambody

关于error

因为request对象是一个ReadableStream流对象,同时又是EventEmitter可以处理事件。所以自然可以监听error事件作错误处理。
若没有监听error事件,可能会抛出异常中断Node.js程序


Response

response对象作为响应用户请求,ServerResponse的实例,是一个WritableStream流对象

// 单独写状态码、响应头
response.statusCode = 404;
response.setHeader('Content-Type', 'application/json');
response.setHeader('X-Powered-By', 'bacon');
// 整合到一起写响应头
response.writeHead(200, {
  'Content-Type': 'application/json',
  'X-Powered-By': 'bacon'
});

因为response是流对象,所以可以用流对象方法写内容

response.write('');
response.write('');
response.write('

Hello, World!

'); response.write(''); response.write(''); response.end('
end也可以包含内容
');

简易demo

const http = require('http');

http.createServer((request, response) => {
  const { headers, method, url } = request;
  let body = [];
  request.on('error', (err) => {
    console.error(err);
  }).on('data', (chunk) => {
    body.push(chunk);
  }).on('end', () => {
    body = Buffer.concat(body).toString();
    // 开始对response对象进行操作
    response.on('error', (err) => {
      console.error(err);
    });
    response.writeHead(200, {'Content-Type': 'application/json'})
    const responseBody = { headers, method, url, body };
    response.write(JSON.stringify(responseBody));
    response.end();
    // 结束对response对象操作
  });
}).listen(8080); // 激活服务器,监听8080端口

官方还提供了更加详细的demo描述针对method和url不同(即请求对应url做不同的处理)这里不再做过多解释


总结

官方描述了最为基础的处理HTTP请求的方法

  • 实例化一个带有request处理函数的HTTP服务并监听端口
  • 去请求对象里获取headers, URL, method和body数据
  • 基于URL and/or 其他(例如method)订制路由策略
  • 通过response对象发送头、状态码和body数据
  • 从请求对象到响应对象传输数据
  • 同时处理好request和response流的错误信息

通过这些基础特性,许多基础的Nodejs的HTTP服务就可以被建立起来了。node API doc里面也提供了许多方法可供更复杂的场景使用。


参考

Anatomy of an HTTP Transaction

你可能感兴趣的:(nodejs学习笔记——http事务剖析)