首页 技术 正文
技术 2022年11月19日
0 收藏 436 点赞 2,910 浏览 3437 个字

简单了解 node http 模块

文章记录了对http 模块的简单使用与理解。

  • http 服务端
  • http 客户端
  • 总结

1. http 服务端

先写个小例子

服务端:

let http = require('http')
let server = http.createServer((req, res) => {
let buf = []
req.on('data', data => {
buf.push(data)
})
req.on('end', () => {
let str = Buffer.concat(buf).toString()
res.end(str)
})
})server.listen(8080, () => {
console.log('server start')
})

大概代码执行流程:简单了解 node http(一) http.createServer() 返回新建的 http.Server 实例。http.Server 继承自net.Server。requestListener 是一个自动添加到到 ‘request’ 事件的函数。’request’ 事件 每次请求的时候都会触发。http服务是以request为单位进行服务的。http.IncomingMessage 对象,它可用于访问本次,请求的请求方法、消息头、以及数据(图中将,请求头与数据拆分开)。http.ServerResponse 对象,服务端通过http.ServerResponse 实例,来给客户端(数据请求方)返回本次数据。包括响应头,响应体(内部通过socket来发送信息)。http服务端:在TCP模块套接字 socket 上,将接受的数据解析出请求报文头和报文主体,将返回的响应报文头和报文主体组装成数据发送出去。

1.1 请求:

简单了解 node http(一)

请求报文由以下组成

  • 报文首部:请求方法、请求 URI、协议版本、可选的请求首部字段等
  • 空行
  • 报文主体:内容实体构成数据。

简单了解 node http(一)

node http 模块 在TCP连接的读操作上,将数据解析成(以空行分割,报文头和报文体):

报文头部分:
req.method

req.httpVersionMajor
req.httpVersionMinor
req.httpVersion
req.upgrade
...
req.headers = {
Content-Length: 15
Content-Type: application/x-www-form-urlencoded
... ...
}
//
报文主体部分:
一个可读流对象req,可以继续报文主体数据的读取

1.2响应

服务端通过http.ServerResponse 实例,来向客户端(数据请求方)返回本次请求数据。包括响应头,响应体(内部通过socket来发送信息)。

node http 模块 在TCP连接的写操作上,将数据写缓存拼接(以空行拼接,报文头和报文体)成:

//中间有个空行
"HTTP/1.1 200 OK
Date: Sat, Nov :: GMT
Connection: close
Content-Length: "
+ 请求体部分数据或全部数据

通过的方法

// 具体使用参考文档// 设置头部,头部并没有发送
response.setHeader(name, value)
// 设置头部,向请求发送响应头,此方法只能在消息上调用一次,并且必须在调用 response.end() 之前调用。
response.writeHead()
// 如果调用此方法并且尚未调用 response.writeHead(),则将切换到隐式响应头模式并刷新隐式响应头。
// 这会发送一块响应主体。 可以多次调用该方法以提供连续的响应主体片段。
response.write()
// 此方法向服务器发出信号,表明已发送所有响应头和主体,该服务器应该视为此消息已完成。 必须在每个响应上调用此 response.end() 方法。
response.end()

2. http 客户端

客户端向 HTTP服务器发起请求:

let http = require('http')
let options = {
host: 'localhost',
port: 8080,
method: 'POST',
headers: {
'content-type': 'application/x-www-form-urlencoded'
}
}
// 请求并没有 发出 req 是个可写流
let req = http.request(options)req.on('response', res => {
console.log(res.headers)
let buf = []
res.on('data', data => {
buf.push(data)
})
res.on('end', () => {
console.log(Buffer.concat(buf).toString())
})
})
// write 向请求体写数据
req.write('name=luoxiaobu&title=http')
// 实际的请求头将会与第一个数据块一起发送,或者当调用 request.end() 时发送。
req.end()

大概代码执行流程:

简单了解 node http(一)

http.request() 返回 http.ClientRequest 类的实例。http.ClientRequest 内部创建了一个socket来发起请求。

ClientRequest 实例是可以看做可写流。如果需要使用 POST 请求上传文件,则写入到 ClientRequest 对象。

response事件 每次服务器端有数据返回响应时都会触发。

http.IncomingMessage 对象,它可用于访问本次服务器端返回的,响应状态、消息头、以及数据。

http客户端:在TCP模块套接字 socket 上,将求报文头和报文主体组装成数据发送出去,将接受的数据解析出响应报文头和报文主体,。

2.1 请求:

node http 模块 在TCP连接的写操作上,将数据缓存拼接(以空行拼接,报文头和报文体)成:

//中间有个空行
"POST / HTTP/1.1
content-type: application/x-www-form-urlencoded
Host: localhost:8080
Connection: close
Transfer-Encoding: chunked"
+ 请求体部分数据或全部数据

通过的方法

// 具体使用参考文档
const postData = querystring.stringify({
'msg': '你好世界'
});const options = {
hostname: 'localhost:8080',
path: '/upload',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(postData)
}
};
// 内部会处理 options 解析出头部
const req = http.request(options, (res) => {});// 这会发送一块响应主体。 可以多次调用该方法以提供连续的响应主体片段。
response.write()
// 此方法向服务器发出信号,表明已发送所有响应头和主体,该服务器应该视为此消息已完成。 必须在每个响应上调用此 response.end() 方法。
response.end()

2.2 响应

响应报文图:

简单了解 node http(一)

响应报文由以下组成

  • 报文首部:协议版本、状态码(表示请求成功或失败的数字代码)、用以解释状态码的原因短语、可选的响应首部字段
  • 空行
  • 报文主体:实体主体构成。

简单了解 node http(一)

node http 模块 在TCP连接的读操作上,将数据解析成:

报文头部分:
res.statusCode = statusCode;
res.statusMessage =
statusMessage;
res.httpVersionMajor
res.httpVersionMinor
res.httpVersion
res.upgrade
...
res.headers = {
Content-Length: 15
Content-Type: application/x-www-form-urlencoded
... ...
}
//
报文主体部分:
一个可读流对象,可以继续报文主体数据的读取

3. 总结

文章记录了对http 模块的简单使用与理解,要深入理解http 模块,还需多看文档,代码实践。

文中例子比较粗糙,理解不准确之处,还请教正。

参考资料:<<图解HTTP>>

https://nodejs.org/dist/latest-v13.x/docs/api/http.html

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,022
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,513
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,359
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,142
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,773
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,851