HTTP模块

NodeHTTP模块包含对http处理的封装。在node中,HTTP服务继承自TCP服务器(net模块),它能够与多个客户端保持连接,由于其采用时间驱动的形式,并不为每一个连接创建额外的线程或进程,保持很低的内存占用,所以能实现高并发。


HTTP服务于tcp服务模型的比较

区别

  • 在开启Keepalive后,一个TCP会话可以用于多次请求和响应。
  • 理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连 接之前,TCP 连接都将被一直保持下去。
  • HTTP在每次请求结束后都会主动释放连接,因此HTTP连接是一种“短连接”.
  • TCP服务以connection为单位进行服务,HTTP服务以request为单位进行服务。
  • HTTP模块即是将connection到request的过程进行的封装。
    联系
  • http是要基于TCP连接基础上的,TCP就是单纯建立连接,不涉及任何我们需要请求的实际数据,简单的传输。
    http是用来收发数据,即实际应用上来的。
  • 客户端和应用服务器建立TCP连接之后,就需要用http协议来传送数据了,HTTP协议简单来说,还是请求,确认,连接。

HTTP流程

HTTP模块将连接所用套接字的读写抽象为ServerRequestServerResponse对象,它们对应请求和响应操作。在请求产生的过程中,HTTP模块拿到连接中传来的数据,调用二进制模块http_parser进行解析,在解析完请求报文得我爆头后,触发request事件,调用用户的业务逻辑。

HTTP流程的示意图

HTTP模块产生请求的过程

上面的处理程序对应到的代码就是下面响应Hello World这部分,代码如下:

function(req, res){
  res.wirteHead(200,{'content-type': 'textt/plain'});
  res.end(' Hello World ')
}

HTTP请求

对于TCP连接的读操作,http模块将其封装为serverRequest对象。
通过curl获取http服务的报文,报文的头部会通过http_parser进行解析。报文如下:

> GET / HTTP/1.1
> Host: 127.0.0.1:1337
> User-Agent: curl/7.55.1
> Accept: */*

报文头第一行 GET / HTTP/1.1被解析之后分解为如下属性。

  • req.method属性:值为GET,是为请求方法,常见的请求方法有GET、POST、DELETE、PUT、CONNECT等几种。
  • req.url属性:值为/
  • req.httpVersion属性:值为1.1

其余报文都是很规律的key:value格式,被解析后放置在req.headers属性上传递给业务逻辑以供调用,如下:

headers:{
  User-Agent: curl/7.55.1,
  Host: 127.0.0.1:1337,
  Accept: */*
}

报文体部分则抽象为一个制度对象,如果业务逻辑需要读取报文体中的数据,则要在这个数据流结束后才能进行操作,如下:

function (req, res) {
    console.log(req.headers);
    var buffers = [];
    req.on('data', function (trunk) {
        buffers.push(trunk);
    }).on('end', function () {
        var buffer = Buffer.concat(buffers);
        //TODO
        res.end('hello world')
    });
}

HTTP请求对象和HTTP响应对象是相对较底层的封装,web框架如ConnectExpress都是在这两个对象基础上进行搞成封装完成的。

HTTP响应

HTTP响应对象相对简单一些,它封装了对底层连接的写操作,可以将其看成一个可写的流对象。它影响响应报文头部信息的API为res.setHeader()和res.weiteHead():

res.writeHead(200, {'Content-Type':'text/plain'});

其分为setHeader()writeHead()两个步骤。它在http模块封装下,实际生成如下报文:

< HTTP/1.1 200 OK
< Content-Type: text/plain
  • 可调用setHeader进行多次设置,但只有调用writeHead后,报文才会写入到连接中。

HTTP模块会自动帮你设置一些头信息:

< Date: Wed, 11 Mar 2020 08:32:20 GMT
< Connection: keep-alive
< Transfer-Encoding: chunked
  • 报文体部分则是调用res.write()res.end()方法实现。
  • res.end()res.write()差别在于end()会先调用write()发送数据,然后发送信号告知服务器这次响应结束。
  • 响应结束后,HTTP服务器可能会将当前的链接用于下一个请求,或者关闭链接。
  • 报头是在报文体发送前发送,一旦开始了数据的发送,writeHeadsetHeader将不会在生效。
  • 服务端在处理业务逻辑时无论是否发生异常,务必在结束时调用res.end的方式结束请求,以防客户端一直处于等待的状态。
  • 可通过延迟res.end的方式实现客户端与服务端之间的长度连接,但是结束时务必关闭链接。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,552评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,666评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,519评论 0 334
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,180评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,205评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,344评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,781评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,449评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,635评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,467评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,515评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,217评论 3 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,775评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,851评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,084评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,637评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,204评论 2 341

推荐阅读更多精彩内容

  • http模块创建服务: 使用createServer返回一个http.Server对象,这个对象就是一个服务器...
    stringtoString阅读 1,043评论 0 1
  • 以下内容来自:Node.js开发指南。在此感谢原作者提供的帮助! HTTP 服务器与客户端 Node.js 标准库...
    沈祥佑阅读 476评论 0 2
  • Ryan Dahl开发node的初衷就是:把Nginx非阻塞IO功能和一个高度封装的WEB服务器结合在一起的东东。...
    IT老马阅读 1,423评论 0 6
  • Ryan Dahl开发node的初衷就是:把Nginx非阻塞IO功能和一个高度封装的WEB服务器结合在一起的东东。...
    中v中阅读 348评论 0 0
  • 复盘昨天的行为和思考 升级思维方式最重要 没有选择原来是多年来我没法投入工作的内在原因! 同事做事方式不喜欢,没法...
    Sam峰鸿阅读 107评论 0 0