node.js 入门教程之十 -- http 模块
http 模块是 node.js 处理 networking 网络的关键模块。在之前的章节我介绍了使用 http 模块建立 server 以及发起 GET/POST 请求的方法,可以参考:https://blog.niekun.net/archives/2137.html
http 模块集成于 node.js 核心无需单独安装,使用下面命令引入模块:
const http = require('http')
模块提供了很多 properties,methods 和 classes。
Properties 属性
http.METHODS
http.METHODS property 返回 http 所有的可用 method 列表:
> console.log(require('http').METHODS)
[
'ACL', 'BIND', 'CHECKOUT',
'CONNECT', 'COPY', 'DELETE',
'GET', 'HEAD', 'LINK',
'LOCK', 'M-SEARCH', 'MERGE',
'MKACTIVITY', 'MKCALENDAR', 'MKCOL',
'MOVE', 'NOTIFY', 'OPTIONS',
'PATCH', 'POST', 'PRI',
'PROPFIND', 'PROPPATCH', 'PURGE',
'PUT', 'REBIND', 'REPORT',
'SEARCH', 'SOURCE', 'SUBSCRIBE',
'TRACE', 'UNBIND', 'UNLINK',
'UNLOCK', 'UNSUBSCRIBE'
]
http.STATUS_CODES
http.STATUS_CODES 返回所有的 http 状态码及描述的 list 列表:
> console.log(require('http').STATUS_CODES)
{
'100': 'Continue',
'101': 'Switching Protocols',
'102': 'Processing',
'103': 'Early Hints',
'200': 'OK',
'201': 'Created',
'202': 'Accepted',
'203': 'Non-Authoritative Information',
'204': 'No Content',
'205': 'Reset Content',
'206': 'Partial Content',
'207': 'Multi-Status',
'208': 'Already Reported',
'226': 'IM Used',
'300': 'Multiple Choices',
'301': 'Moved Permanently',
'302': 'Found',
'303': 'See Other',
'304': 'Not Modified',
'305': 'Use Proxy',
'307': 'Temporary Redirect',
'308': 'Permanent Redirect',
'400': 'Bad Request',
'401': 'Unauthorized',
'402': 'Payment Required',
'403': 'Forbidden',
'404': 'Not Found',
'405': 'Method Not Allowed',
'406': 'Not Acceptable',
'407': 'Proxy Authentication Required',
'408': 'Request Timeout',
'409': 'Conflict',
'410': 'Gone',
'411': 'Length Required',
'412': 'Precondition Failed',
'413': 'Payload Too Large',
'414': 'URI Too Long',
'415': 'Unsupported Media Type',
'416': 'Range Not Satisfiable',
'417': 'Expectation Failed',
'418': "I'm a Teapot",
'421': 'Misdirected Request',
'422': 'Unprocessable Entity',
'423': 'Locked',
'424': 'Failed Dependency',
'425': 'Too Early',
'426': 'Upgrade Required',
'428': 'Precondition Required',
'429': 'Too Many Requests',
'431': 'Request Header Fields Too Large',
'451': 'Unavailable For Legal Reasons',
'500': 'Internal Server Error',
'501': 'Not Implemented',
'502': 'Bad Gateway',
'503': 'Service Unavailable',
'504': 'Gateway Timeout',
'505': 'HTTP Version Not Supported',
'506': 'Variant Also Negotiates',
'507': 'Insufficient Storage',
'508': 'Loop Detected',
'509': 'Bandwidth Limit Exceeded',
'510': 'Not Extended',
'511': 'Network Authentication Required'
}
http.globalAgent
http.globalAgent 指向 http.Agent class 的一个 instance 实例,也就是一个 Agent object。
这个 Agent object 用来管理 server 同 http 客户端链接的持续连接和链接复用,这也是 node.js 网络服务的关键点。
> console.log(require('http').globalAgent)
Agent {
_events: [Object: null prototype] {
free: [Function (anonymous)],
newListener: [Function: maybeEnableKeylog]
},
_eventsCount: 2,
_maxListeners: undefined,
defaultPort: 80,
protocol: 'http:',
options: { path: null },
requests: {},
sockets: {},
freeSockets: {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: Infinity,
maxFreeSockets: 256,
scheduling: 'lifo',
maxTotalSockets: Infinity,
totalSocketCount: 0,
[Symbol(kCapture)]: false
}
methods 功能
http.createServer()
http.createServer()
返回一个 http.Server class 实例。
const server = http.createServer((req, res) => {
//handle every single request with this callback
})
http.request()
http.request()
对服务器发起一个 http 请求。返回一个 http.ClientRequest class 实例。
const options = {
hostname: 'localhost',
port: 3000,
path: '/',
method: 'GET'
}
const req = https.request(options, res => {
console.log(`statusCode is:${res.statusCode}`);
res.on('data', d => {
process.stdout.write(d)
})
})
req.on('error', err => console.log(err))
req.end()
http.get()
http.get()
同 http.request()
类似,但会自动将 http method 设置为 GET,且自动调用 req.end()
。
const https = require('http')
const options = {
hostname: 'localhost',
port: 3000,
path: '/'
}
const req = https.get(options, res => {
console.log(`statusCode is:${res.statusCode}`);
res.on('data', d => {
process.stdout.write(d)
})
})
req.on('error', err => console.log(err))
Classes 类
http 模块提供 5 个 calsses:
- http.Agent
- http.ClientRequest
- http.Server
- http.ServerResponse
- http.IncomingMessage
http.Agent
node.js 会创建一个全局的 http.Agent instance 实例来管理 server 同 http 客户端链接的持续连接和链接复用,这个 object 可以确保一个客户端对服务端发起的一系列请求是按队列排序的,且使用单独的 socket 接口。同样 agent object 管理着一个 sockets 池,这是影响性能的关键因素。
http.ClientRequest
当 http.request()
或 http.get()
被调用时会创建一个 http.ClientRequest object。
当收到来自服务器的 response 时,response event 会被触发,http.request()
内定义的 callback 会作为 response 的响应被调用,同时将 http.IncomingMessage 的实例作为传入参数,其中包含了 response 数据。
response 数据有两种方式读取,第一种是通过 response.read()
method,第二种是在 response 的 callback function 中通过监听 data event 来获取 stream 中的数据。
http.Server
当通过 http.createServer()
创建一个 server 时会返回 http.Server 实例。 http.Server 实例需要使用它的以下 method:
close()
停止 server 接收新的链接listen()
启动 server 并开始监听请求
http.createServer()
的 callback 监听 request event 并响应。
http.ServerResponse
由 http.Server object 创建,作为 request event 的第二个参数传入,代码中作为 callback 的 res 参数使用:
const server = http.createServer((req, res) => {
//res is an http.ServerResponse object
})
end()
是 http.ServerResponse object 必须被使用的 method,用来表示 response 信息已经完整,可以结束这个 response,同时将 response 发送出去。
下面的 method 可以用来处理 http headers:
- getHeaderNames() 获取当前 http headers 名称的列表
- getHeaders() 获取当前 http headers 副本
- setHeader('headername', value) 设置一个 http header
- getHeader('headername') 获取当前的一个 http header 的设置
- removeHeader('headername') 删除一个 http header
- hasHeader('headername') 如果某个 http header 有被设置则返回 true
- headersSent() 如果 http headers 已经发送给了客户端则返回 true
服务端编辑好 headers 条目后可以通过 response.writeHead()
method 发送给客户端,第一个参数是 statusCode。
通过 response.write()
在 response body 中发送数据给客户端,它会将缓冲区的数据发送到 http response stream。如果还没有使用 response.writeHead()
发送 headers 则会先发送 headers,包含 statusCode 和 message,它们可以通过下面语法设置:
response.statusCode = 500
response.statusMessage = 'Internal Server Error'
http.IncomingMessage
http.IncomingMessage 可以在以下两个地方创建:
- http.Server 当监听 request event
- http.ClientRequest 当监听 response event
它可以用来访问 response 数据:
- 通过 statusCode 和 statusMessage 读取状态信息
- 通过 headers method 或 rawHeaders method 读取 headers 信息
- 通过 method method 获取可用 http method
- 通过 httpVersion method 获取 http 版本信息
- 通过 url method 获取 URL 信息
- 通过 socket method 获取底层 socket 信息
在 http.IncomingMessage 生效一个可读的 stream 接口后,数据可在 stream 中读取。
标签:无