简单了解 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')
})
大概代码执行流程:
 
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 请求:

请求报文由以下组成

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

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()

大概代码执行流程:

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 模块 在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

简单了解 node http(一)的更多相关文章

  1. node.js学习(三)简单的node程序&&模块简单使用&&commonJS规范&&深入理解模块原理

    一.一个简单的node程序 1.新建一个txt文件 2.修改后缀 修改之后会弹出这个,点击"是" 3.运行test.js 源文件 使用node.js运行之后的. 如果该路径下没有该 ...

  2. 简单的node爬虫练手,循环中的异步转同步

    简单的node爬虫练手,循环中的异步转同步 转载:https://blog.csdn.net/qq_24504525/article/details/77856989 看到网上一些基于node做的爬虫 ...

  3. 搭建一个最简单的node服务器

    搭建一个最简单的node服务器 1.创建一个Http服务并监听8888端口 2.使用url模块 获取请求的路由和请求参数 var http = require('http'); var url = r ...

  4. 简单了解 node net 模块

    简单了解 node net 模块 文章记录了对net 模块的简单理解分析. net模块 简单使用 net.Server 类 net.Socket 类 总结 1.1 net模块 Node.js 的 Ne ...

  5. 简单了解node stream

    Almost all Node.js applications, no matter how simple, use streams in some manner. 开篇先吓吓自己.画画图,分析分析代 ...

  6. 用简单的 Node.js 后台程序浅析 HTTP 请求与响应

    用简单的 Node.js 后台程序浅析 HTTP 请求与响应 本文写于 2020 年 1 月 18 日 我们来看两种方式发送 HTTP 请求,一种呢,是命令行的 curl 命令:一种呢是直接在浏览器的 ...

  7. 一个超级简单的node.js爬虫(内附表情包)

    之所以会想到要写爬虫,并不是出于什么高大上的理由,仅仅是为了下载个表情包而已-- 容我先推荐一下西乔出品的神秘的程序员表情包. 这套表情包着实是抵御产品.对付测试.嘲讽队友.恐吓前任的良品, 不过不知 ...

  8. 简单剖析Node中的事件监听机制(一)

    使用js的class类简单的实现一个事件监听机制,不同于浏览器中的时间绑定与监听,类似于node中的时间监听,并且会在接下来的文章中去根据自己的理解去写一下Event模块中的原理. Node.js使用 ...

  9. 一个用来爬小说的简单的Node.js爬虫

    小说就准备点天下霸唱和南派三叔的系列,本人喜欢看,而且数据也好爬.貌似因为树大招风的原因,这两作者的的书被盗版的很多,乱改的也多.然后作者就直接在网上开放免费阅读了,还提供了官网,猜想作者应该是允许爬 ...

随机推荐

  1. ShiroFilterFactoryBean 找不到的原因

    是因为参考的那篇shiro的博客,没有引入这个依赖的原因 <dependency> <groupId>org.apache.shiro</groupId> < ...

  2. 2019年6月Github最新开源java项目

    目录 1.halo,这是一个轻快,简洁,功能强大,使用Java开发的博客系统. 2.jeecg-boot 3.CS-Notes 4.JavaGuide 5.advanced-java 6.mall-l ...

  3. Java第09次实验(IO流)--实验报告

    0.字节流与二进制文件 我的代码 用DataOutputStream和FileOutputStream将Student对象写入二进制文件student.data package test; impor ...

  4. Windows下安装TensorFlow教程

    目录 安装Python3.6 配置环境变量 安装TensorFlow 验证安装 报错或选版本 安装Python3.6 建议直接安装anaconda 下载地址:https://www.anaconda. ...

  5. leetcode-easy-design-155 Min Stack

    mycode   21.48% class MinStack(object): def __init__(self): """ initialize your data ...

  6. java 设计模式 单例模式之饿汉模式/懒汉模式 singleton pattern

    https://v.qq.com/x/page/e0364ung5zp.html 讲的不错, 关于 饿汉式单例模式 code Student 类: package com.test;//单例模式之   ...

  7. ERROR:非静态成员引用必须与特定对象相对

    非静态成员引用必须与特定对象相对 引用非静态成员前应该先声明该类的对象 typedef struct _SUPERRESOLUTIONPARAM { int Times; //重建倍数,指的是分别对长 ...

  8. win10 点击开始按钮无反应

    本人亲身经历 由于安装软件时需要注册表权限,在一顿猛如虎的操作下,将注册表中 HKEY_CURRENT_USER 的权限出问题.而导致无法打开 开始菜单 ----------------以下是本人为了 ...

  9. 无界面上(linux)生成测试报告(3)

    无界面上(linux)生成测试报告 1.待jmx文件运行完成后,键入命令进入到jtl文件下: #cd testresult#bin目录下使用此命令,进入到jtl文件下 #jmeter -g pushG ...

  10. 阶段3 2.Spring_08.面向切面编程 AOP_8 spring中的环绕通知

    环绕通知.method属性需要新加一个方法 在logger内中新加aroundPringLog方法 异常代码先注释掉 对比现在的环绕通知和之前写代理类做的环绕通知.右侧的方法内有明确的业务层方法(切入 ...