详解Node Http模块

nodehttp

Jmingzi createdAt at 3年前

概述

node http 同时支持服务端和客户端功能

  • http.createServer
  • http.request

关联知识点:

  • Stream可写或可读流,Buffer、fs、Stream之间的关系
  • EventEmitter事件发射器,即发布订阅的关系

http模块的类、属性和方法

http模块中,有几个类,很多对象都是这些类的实例

  • http.Server
  • http.ServerResponse
  • http.ClientRequest
  • http.IncomingMessage
  • http.Agent

http模块中,还有几个方法和属性

  • http.METHODS
  • http.STATUS_CODES
  • http.globalAgent
  • http.createServer()
  • http.get()
  • http.request()

http模块服务端的介绍

创建http服务器,从上面罗列的类和方法可以看出有2种方式

const http = require('http')

// 方法 1
const server = new http.Server()
server.on('request', (req, res) => {
  res.end()
})

// 方法 2
const server = http.createServer((req, res) => {
  res.end()
})

从上面可以得出以下结论

  • createServer方法就是对new http.Server()的封装,其接收的回调函数,也就是事件request的回调
  • 它们都会得到Server类的实例
  • 回调中,都会接收2个参数,requestresponse,此时,requestIncomingMessage的实例,responseServerResponse的实例

上面我们提到事件发射器,此处的Server就是一个事件发射器,它发射的事件有:

  • request 每次接收到一个请求时触发
  • connect 每当客户端发送 HTTP CONNECT 请求时触发
  • connection 当新的 TCP 流被建立时触发,例如socket连接
  • close
  • clientError 如果客户端触发了一个 ‘error’ 事件,则它会被传递到这里
  • upgrade
  • checkContinue
  • checkExpectation

Server类还有一些方法:

  • server.listen() 创建服务器后,监听端口以启动连接
  • server.close()
  • server.setTimeout()

介绍完创建http服务实例的server对象,我们再来看看返回的2个对象IncomingMessage的实例和ServerResponse的实例

从上面创建http服务的代码中可以看到,我们会使用res对象的方法去做一些事情,用以响应客户端的请求,它也是一个EventEmitter

关于响应体,我们知道有头部和实体,ServerResponse对头部的操作:

  • res.writeHead(statusCode[, statusMessage][, headers])
    res.writeHead(200, 'OK', { 'Content-Type': 'text/plain' })
    
  • res.setHeader(name, value)
  • res.getHeader(name)
  • res.removeHeader(name)

对实体的方法

  • res.write(chunk[, encoding][, callback])
    • chunk String|Buffer,当为字符串时,第二个参数指定字符串如何编码成字节流,encoding默认为utf8
  • response.end([data][, encoding][, callback])
    • 该方法会通知服务器,所有响应头和响应主体都已被发送,即服务器将其视为已完成。 每次响应都必须调用 response.end() 方法。
    • 如果指定了 data,则相当于调用 response.write(data, encoding) 之后再调用 response.end(callback)。
    • 如果指定了 callback,则当响应流结束时被调用。

再来看另外一个类IncomingMessage,此时为客户端请求对象,同样的,它也是一个EventEmitter,它包含了2个方法message.destroy()message.setTimeout(),另外最常用的是它的属性:

  • message.headers 查看客户端请求的头部信息
  • message.method
  • message.url
  • message.statusCode

IncomingMessage不仅在http作为服务端时作为实例传递,也在http作为客户端时实例化,不同的时候,参数略有不同,例如message.url仅对作为服务器时有效,而message.statusCode在作为客户端时有效,因为在作为服务器时表request含义,在作为客户端时,表response含义。下面我们再来看看,作为客户端时的情况。

http模块客户端的介绍

从最开始的属性与方法中我们可以看到有2种方法可以作为客户端时使用,并且与之相关的类为ClientRequestIncomingMessage

  • http.request(options[, callback])
  • http.get(options[, callback])
    • 该方法是对request的封装,唯一区别是设置method为GET且自动调用了req.end()
    • 该方法不带有请求主体,即request.write(chunk[, encoding][, callback]),而quest当method为post时是需要带的

我们先来看IncomingMessage,此时作为响应体对象response在回调中返回,通常情况下,我们添加这个回调函数用以接收response对象来处理响应结果,此时必须手动处理掉response,因为它是存在内存中的,有三种方法:

  • response.read()
  • response.on(‘data’, chunk => { })
  • response.resume()

此时我们可以查看IncomingMessage中对于作为客户端response时的有效属性的含义。

ClientRequest类,它的实例是在request调用时创建。

// request 为ClientRequest实例
const request = http.request() 

当使用post传递参数时,可以将参数以流的形式写入到请求主体中

request.write(formData)
request.end()

其他属性

  • http.METHODS 返回解析器支持的 HTTP 方法的列表
  • http.STATUS_CODES 返回标准的 HTTP 响应状态码的集合,以及各自的简短描述
    { '100': 'Continue',
    '101': 'Switching Protocols',
    '102': 'Processing',
    '200': 'OK' ... }
    

参考

git0

最后更新:2021年06月09日 16:00

鄂ICP备18011687号-1