千家信息网

Node中怎么处理HTTP请求

发表于:2025-02-04 作者:千家信息网编辑
千家信息网最后更新 2025年02月04日,本篇文章给大家分享的是有关Node中怎么处理HTTP请求,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。首先使用express gener
千家信息网最后更新 2025年02月04日Node中怎么处理HTTP请求

本篇文章给大家分享的是有关Node中怎么处理HTTP请求,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

首先使用express generator快速搭建一个express项目,命令:

express analysis_http

按照提示进入项目安装依赖,然后使用npm start可以启动express项目。那究竟我们项目是如何创建http服务器并且进行启动的呢?express创建成功会在bin文件夹下生成www文件,里面有必须的启动配置。我们可以看看www文件:

我们初步可以看到,主要调用了http.createServer()server.listen()两个方法。我们现在可能会有一系列疑问:

接口使用的req和res参数从何而来?createServer()如何创建服务器?listen()具体是进行了什么样的操作?

接下来,我们通过源码来具体分析这些问题。首先,从gitHub拉取一份NodeJS源码,地址:

https://github.com/nodejs/node.git

我们先来查看lib/http.js文件关键代码:

我们可以看到createServer()方法返回的是Server的一个实例。而参数requestListener我们我们接口中的传入的回调函数:

function(req, res, next) {    res.send('respond with a resource');}

在文件顶部可以看到Server引用的_http_server.js。所以我们去_http_server.js中看看Server这个构造函数:

由于Server继承net.Server,net.Server继承自events.EventEmitter所以可以使用on等方法。我们可以看到在Server构造函数中设置了requestconnection事件的回调函数:

request使用了createServer中设置的回调方法requestListener。connection则使用了回调方法:connectionListener。

那我们什么时候会触发connection事件呢?我们看下connectionListener关键源码:

这里比较需要注意的有parser对象以及parseOnIncoming()。我们先来看看parser对象,parser来自parsers.alloc():

const parser = parsers.alloc();

从文件顶部可以看出parsers来自_http_common.js文件。我们可以看看源码:

我们可以看到,为了尽可能增加对parser进行重用,减少不断调用构造函数的消耗,parser采用了FreeList的数据结构,FreeList池中设有上限1000parser是基于事件,使用了http-parser库。然后可以看到两个比较重要的方法:parseOnHeadersCompleteparserOnMessageComplete

parseOnHeadersComplete:请求头解析完成则触发本方法。parserOnMessageComplete:接收body完成后触发本方法,数据接收完成会触发end事件。

我们再来看看FreeList的源码:

http默认创建了1000http_parser实例,每次有http请求时,都会从数组中去除一个http_parser分配给当前的socket。如果1000http_parser全部分配完毕,则会分配新的http_parser。我们解析完请求头会触发parseOnHeadersComplete方法,如果不是udp类型请求,就会触发request事件。

讲完了parser对象,我们接着回到刚才说的parseOnInComing()方法。parseOnInComing()方法使用bind,并传入参数parser,socket,state。

parser.onIncoming = parserOnIncoming.bind(undefined, server, socket, state);

我们先看看parseOnInComing()的源码:

里面有个重要的判断为sockket._httpMessage。如果结果为true,说明有其他请求在占用socket。而parserOnInComing()方法用来处理解析完毕的请求,所以到这里代表解析请求头和请求体已经完成了。而刚才已经讲过:请求头解析完毕会执行parserOnHeadersComplete()方法,我们看看parserOnHeadersComplete()方法的源码:

我们可以看到里面调用了parser.incoming,parser.incoming则是ParserInComingMessage(socket)的一个实例。ParserInComingMessage继承自Stream.Readable。StreamNodeJS另一个尤其重要的知识点,不过本篇文章不进行深入讲解。

Object.setPrototypeOf(IncomingMessage.prototype, Stream.Readable.prototype);Object.setPrototypeOf(IncomingMessage, Stream.Readable);

所以整体的逻辑应该为:

1.解析请求头,就会触发request事件。2.请求头解析完毕执行parserOnHeadersComplete()方法。3.在parserOnHeadersComplete()方法中执行了parseOnIncoming()方法。4.最后server.emit('request', req, res)。

在触发request事件的时候,传入req, res参数。因为一开始我们说过了request绑定了回调方法:

function(req, res, next) {    res.end('respond with a resource');}

所以触发request的时候回调方法被执行。但是body数据不会被解析,而body数据会一直存放在stream中,直到用户触发data事件来接收body中的数据。回调方法中会触发res.end()事件。那究竟listen()是做了什么操作呢?

因为只有connection事件被触发,才会触发listen()事件。所以先看下onconnection()源码:

我们接着查看调用onconnection()方法的源码:

setupListenHandle(address, port, addressType, backlog, fd)

可以看到底部使用了_listen2。我们继续查看调用_listen2源码:

可以看到内部调用了server._listen2。我们再次查看调用listenInCluster的源码:

我们是使用递推,由下往上推出调用的方法,所以整体的流程应该是:

1.listen()调用listenInCluster(this, pipeName, -1, -1, backlog, undefined, options.exclusive);2.在listenInCluste()中调用server._listen2(address, port, addressType, backlog, fd, flags);3.接着调用了setupListenHandle(address, port, addressType, backlog, fd, flags);4.在setupListenHandle()中调用了onconnection()。5.最终回到listen()方法并且self.emit('connection', socket);

以上就是Node中怎么处理HTTP请求,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注行业资讯频道。

方法 事件 源码 文件 函数 数据 参数 项目 处理 重要 实例 对象 时候 知识 中设 分配 两个 关键 接口 整体 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 网络安全创新体验中心 虹口区节能软件开发服务试验设备 未连接服务器华为是因为 哪家彩票软件开发商好 数据库2000怎么改密码 mysql数据库慢日志 第三方云服务器分布式集群 美体视频软件开发 戴尔服务器v4不支持 健康管理师数据库备案怎么办 学习行业软件开发的收获 软件开发新手老怕软件出问题 法度互联网科技有限公司招聘 常熟运营网络技术哪家好 如何看服务器几个网口几个电口 常州寰宇天下网络技术有限公司 怎么修改服务器的下载权限 公需网络安全考试答案 全球前十大互联网科技公司 南京品质联想服务器工厂 手机版远程服务器 mdb数据库转sql windows搭建远程访问服务器 广州九九玖互联网科技 数据库应用技术电大期末考试 网络安全规划方法 数据库备份文件能修改吗 电脑服务器生产线厂家地址 一个美女软件开发工程师 数据库概念设计如何写
0