简单了解 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. 翻译 | 上手 Webpack ? 这篇就够了!

    译者:小 boy (沪江前端开发工程师) 本文原创,转载请注明作者及出处. 原文地址:https://www.smashingmagazine.com/2017/02/a-detailed-intro ...

  2. JavaScript 普通声明式函数

    1.为什么需要函数 实现代码的复用.存在函数提升,且会在变量提升的上面; 2.函数的创建 js中函数语法: function 函数名(形参){ //函数体 } 调用时:函数名(形参) 注: (1) 形 ...

  3. Android采用pm命令静默卸载应用

    卸载app的方式有多种,可以直接调用android系统的卸载程序,但是这样会调出android卸载提示框,问题就是真的不好看. 所以采用静默卸载的方式,避免弹出系统提示框. 方法一(调用系统卸载程序) ...

  4. echarts_04

    通过ajax加载本地文件: 1.http://www.cnblogs.com/qjqcs/archive/2016/09/07/5850282.html 2.http://blog.csdn.net/ ...

  5. TensorFlow线性回归

    目录 数据可视化 梯度下降 结果可视化 数据可视化 import numpy as np import tensorflow as tf import matplotlib.pyplot as plt ...

  6. IntentService和HandlerThread

    上一篇说了说android 系统的UI更新机制.核心点围绕在Looper的使用上.主线程运行起来后,初始化并运行一个静态Looper,H类(handler子类)处理各种事件. 16ms的UI upda ...

  7. T83312 【音乐会】达拉崩吧·上

    T83312 [音乐会]达拉崩吧·上 题解 线段树板子题 把原来的 + 变成 ^ 但是注意一下懒标记,这里讲一下小技巧 代码 #include<bits/stdc++.h> using n ...

  8. jeecms v9图标不显示问题

  9. [译]深入 NGINX: 为性能和扩展所做之设计

    来自:http://ifeve.com/inside-nginx-how-we-designed-for-performance-scale/ 这篇文章写了nginx的设计,写的很仔细全面, 同时里面 ...

  10. vtk旋转扫描实体示例:vtkQuadRotationalExtrusionFilter、vtkRotationalExtrusionFilter

    一.vtkQuadRotationalExtrusionFilter Detailed Description sweep polygonal data creating "skirt&qu ...