千家信息网

Node中怎么处理HTTP请求

发表于:2024-10-27 作者:千家信息网编辑
千家信息网最后更新 2024年10月27日,本篇文章给大家分享的是有关Node中怎么处理HTTP请求,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。首先使用express gener
千家信息网最后更新 2024年10月27日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安全错误 数据库的锁怎样保障安全 营口软件开发培训班 新手过三级数据库 移动电子商务网络安全对策 哪些服务器的cpu是amd的 兆芯服务器和龙芯服务器 华三服务器管理口密码修改 宝塔数据库地址什么意思 天津浪潮服务器虚拟化安装云空间 作文 班会 网络安全 苏州市民卡 软件开发 智能硬软件开发设计报价 大华运维管理服务器默认密码 学生沉迷网络安全排查报告 泗阳环保网络技术价格查询 网络安全是国家安全的第几要素 网络安全世界技能大赛山东 战术小队有哪几个服务器 大唐无双零最强服务器 阿里云服务器占用高列表不显示 泰拉瑞亚777端口的服务器 数据库集群看节点 一般服务器多少功率 服务器u盘启动按哪个键 网络安全工程师密码 2018网络安全排行榜 沈阳纳深网络技术有限公司 苹果提取图片里的数据库 网络技术三级考试app 自建站外贸服务器选择 国家网络安全知识题和答案
0