Node6.9.2 —— Http官网笔记整理
欢迎指导与讨论 : )
序章
本文概要:http.Agent代理、http.ClientRequest客户端请求、http.server服务器、http.ServerResponse服务器相应、http.InComingMessage报文、http.METHODS方法、http.STATUS_CODES状态码、httpCreateServer创建服务端、http.get、http.blobalAgent全局代理、http.request请求。
前言
要使用Http服务器和客户端,我们必须引入 http 模块。大多数http报文的头部都像是下面的这个对象,并且值是不会修改的。
{ 'content-length': '123',
'content-type': 'text/plain',
'connection': 'keep-alive',
'host': 'mysite.com',
'accept': '*/*' }
为了支持所有可能的HTTP应用程序,Node.js的HTTP API是非常低级的。 它仅处理流式数据和报文解析。报文解析的结果会被注入到 headers 和 body
http.Agent
http代理。http代理是为http客户端请求中的sockets连接池而使用的。同时http代理会为客户端请求默认设置 Connection: keep-alive 如果没有等待空闲套接字的http请求,该套接字会被关闭。这意味着,Node在负载下依然能保持活动,且不需要开发人员手动关闭http客户端的keep-alive。
在keep-alive情况下,一个底层会话连接可以多次用于请求,默认情况下通过ClientRequest对象对同一服务器发起的http请求最多可以创建5个连接,即调用http客户端同时对一个服务器发起10次http请求时,实质只有5个请求处于并发状态。
可以设置 agent 为true,选择使用http keep-alive。或设置 agent 为false,脱离连接池的管理,使请求不受并发的限制。当然,连接量过大,会影响服务,因为一个http服务器允许同时连接的套接字数量是有限的。此时我们需要手动关于无用的套接字,即 Connection: 'close'
1) new Agent([ options ])
参数有 keepAlive: Boolean 表示将套接字保留在池中以在日后使用 默认false, keepAliveMsecs :Number 表示一段时间内不发送tcp就会关闭当前套接字 若KeepAlive为true则默认1000, maxSockets: number 表示允许当前host下的最大socket数 默认Infinity, maxFreeSockets: number 表示在空闲状态下,保持打开套接字的最大数量,若KeepAlive为true 默认值为256
// api-1 new http.Agent({})
const http = require('http');
var keepAliveAgent = new http.Agent({ keepAlive: true });
options.agent = keepAliveAgent;
http.request(options, onResponseCallback);
2 ) agent.createConnection( options [, callback ])
参数有 options: object 即一个有详细连接信息的对象, callback: function 参数为( err, stream ),且返回一个套接字。
3 ) agent.destroy( )
销毁当前代理中任何正在使用的套接字。通常不需要这样做。但是,如果我们使用启用了KeepAlive的代理,则在知道它将不再使用时显式关闭代理。 否则,套接字可能会在服务器终止它们之前挂起很长时间。
4 ) agent.freeSockets
当使用http keep-alive时,返回含当前等待代理使用套接字数组的对象。不要修改
5 ) agent.getName( options )
option含有 host: string 发出请求的服务器的域名或IP地址, port: number 远程服务器端口, localAddress: string 发出请求时用于网络连接的本地接口
此api获取一组请求选项的唯一名称,以确定是否可以重新使用连接。
6 ) agent.maxFreeSockets 请参照上文
7 ) agent.maxSpckets 请参照上文
8 ) agent.requests 返回包含尚未分配给套接字的请求队列的对象,不要修改。
9 ) agent.sockets 返回包含代理程序当前正在使用的套接字数组的对象,不要修改。
http.ClientRequest
http客户端请求。该对象会在 http.request( ) 返回。它表示一个正在进行中的请求,而且该请求的头部已经被序列化。我们依然可以通过 setHeader getHeader removeHeader 来改变头部的信息。头部的信息会和第一个发送数据块或者即将关闭网络连接的信息一起发送。
我们可以通过为 request 对象添加一个名为 response 的监听器,来获得返回信息。该监听器会在返回信息到达时,被request对象触发。 response 事件会接受一个 http.IncomingMessage 实例的参数。
在 response 事件发生时,我们可以为 response 对象添加一个名为 data 的事件,来获取数据块。同时,若我们没有定义response事件发生时的处理函数,该response会被丢弃。
值得注意的是,若我们添加了一个response事件的处理函数,我们必须从response对象中读取数据,无论是通过 response.read( ) 来获取可读数据,或者是添加 data 事件,又或者是调用 resume 方法。直到数据被读取完, end 事件才会被触发。并且,当数据读取完毕前,它会一直消耗着内存,这有可能最终会报出一个'内存不足'的错误。(注:Node不会检查 Content-Length 和已传输报文体的大小是否相等)
因为request对象implements了'可写流'的接口,因此会有以下的这一些事件钩子:
1)Event: 'abort' function ( ) { } 中止事件。该事件会在请求被客户端中止时触发。(注:浏览器中,可以通过调用XMLHttpRequest对象的abort方法来取消正在进行的http请求 )
2)Event: 'checkExpectation' function ( request, response ) { } 当每次受到带有 Expect 的http请求头部,同时该值不为 100-continue 时,该事件会被触发。若无指定该事件和对应的处理函数,服务器将自动响应417。 注意,当此事件被触发后, request 事件就不会被触发了
3)Event: 'connect' function ( response, socket, head ) { } 。每次服务器使用 CONNECT 方法响应请求时,该事件会被触发。若服务器未添加该事件,客户端将关闭该连接。
var options = {
port: 1337,
hostname: '127.0.0.1',
method: 'CONNECT',
path: 'www.google.com:80'
};
var req = http.request(options);
req.on('connect', (res, socket, head) => {
console.log('got connected!');
})
4)Event: 'continue' function ( ) { } 当服务端返回 '100 Continue' 的相应时触发
5)Event: 'response' function ( response ) { } 客户端接受到服务器的响应时触发。该方法之后被触发一次,且方法内的 response 参数是 http.IncomingMessaeg 的一个实例
6)Event: 'socket' function ( socket ) { } 当一个套接字分配给该请求时发出
7)Event: 'upgrade' function ( response, scoket , head ) { } 每当服务器返回'upgrade'相应时发出。若无添加该事件的监听和处理函数,该连接会被中断。
var options = {
port: 1337,
hostname: '127.0.0.1',
headers: {
'Connection': 'Upgrade',
'Upgrade': 'websocket'
}
};
var req = http.request(options);
req.on('upgrade', (res, socket, upgradeHead) => {
console.log('got upgraded!');
})
同时,request请求对象会具备以下的这些方法
1)request.abort( ) 中止请求。响应中的数据会被丢弃,同时解除已连接的套接字。
2)request.end( [data][, encode][, callback] ) 结束发送的请求。
3)request.setNoDelay([ noDelay ]) 每当套接字被分配到当前请求时,socket.setNoDelay( )会被调用。
4)request.flushHeaders( ) 刷新请求头。出于效率原因,Node会一般都会缓存请求头,直到我们调用 request.end( ) 或者编写第一个request数据块。然后Node会尽力把请求头和数据打包到单个TCP数据包中。我们可以调用request.flushHeader( )来绕过优化并启动请求。
5)request.setSocketKeepAlive( [enable] [, initialDelay] ) 一旦套接字被连接,socket.setKeepAlive( )会被调用。
6)request.setTimeout( timeout [, callback] )一旦套接字被连接,socket.setTimeout( )会被调用。
7)request.write( chunk [, encoding] [, callback]) 发送请求体的一个数据块。通过调用该api,我们能以流的形式将数据传输到服务器。encoding参数默认为'utf8',而callack会在时数据块刷新时被调用。
http.server
该类是继承自'net.Server',同时会具备以下的异步事件
1)Event: 'checkContinue'。每当收到带有 Expect: 100 - continue 的http请求头时触发。若我们没有监听该事件并设置相应的处理函数,服务器会自动响应 100 Continue 当该事件被触发时, request 事件不会被触发
2)Event: 'checkExpectation'。每当收到带有 Expect 的http请求且该值不是 100-continue 时被触发。若没有监听该事件和设置对应的处理函数,服务器会自动返回 417。当该事件被触发时,request事件不会被触发。
3)Event: 'clientError' function ( err, socket ) { } 当客户端连接发出'错误'事件时被触发。此事件监听器的处理函数可以负责关闭底层的套接字。且当该事件发生时,回调函数就不存在request和reponse对象了。因此想发送任何的http相应和其他内容都必须直接写在套接字对象中。
const http = require('http'); const server = http.createServer((req, res) => {
res.end();
});
server.on('clientError', (err, socket) => {
socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
});
server.listen(8000);
4)Event: 'close' 当服务器关闭时触发
5)Event: 'connect' function ( request, socket, head ) { } 。每当收到带有 method: CONNECT 的http请求时被触发。若没有监听该事件,客户端连接会被关闭。
6)Event: 'connection' function ( socket ) { } 每当一个新的TCP流被建立时触发。
7)Event: 'request' function ( request, response ) { } 每当有请求到达时被触发。注:每个连接可以有多个请求( keep-alive connections )。
8)Event: 'upgrade' function ( request, socket, head ) { } 每当带有upgrade的http请求到达时被触发,若没有设置该监听器,客户端连接会被关闭。
http.server也带有以下方法
1)server.close( ) 让服务器停止接受新的连接。
2)server.listen( handle [, callback]) handle可以是一个套接字或者是一个服务器对象。服务器会按照指定的handle来接受连接。
3)server.listen( path [, callback])为指定的path开启连接监听
4)server.listen( port [, hostname] [, backlog] [, callback])
http.server也带有以下属性
1)server.listening: Boolean 服务器是否在监听状态
2)server.maxHeadersCount 限制请求头部的最大数量。默认为1000
3)server.setTimeout( msecs, callback )设置套接字的超时值,并主动触发'timeout'事件。若发生超时,则将套接字作为参数传递。超时值默认为2分钟,在超时发生时,套接字将自动销毁。
4)server.timeout 返回设置的超时时间,默认为2分钟。
http.ServerResponse
该对象在Http服务器内部被创建,并作为第二个参数传递到request事件。同时该对象implements自可写流接口。作为一个EventEmitter,它具有以下的这一些事件。
1)Event: 'close' 表示底层连接已经中断。
2)Event: 'finish' 每当响应被发送时被触发。但这不意味着客户端已经接受到任何响应。
http.ServerResponse的一些方法和属性
1)response.addTrailers( headers ) 该方法为响应头的尾部继续加入其他信息。同时,尾部信息只有在编码合乎响应时才会被发送,若不合适则会被默默丢弃。
response.writeHead(200, { 'Content-Type': 'text/plain',
'Trailer': 'Content-MD5' });
response.write(fileData);
response.addTrailers({'Content-MD5': '7895bf4b8828b55ceaf47747b4bca667'});
response.end();
2)response.end( data [, encoing] [, callback]) 该方法表明所有相应的头部和体部信息都已经发送完毕。注:response.end( ) 必须在每一个相应结束时调用,不然客户端会一直等待。
3)response.finished 返回响应是否已经全部完成
4)response.getHeader( name ) 读取一部分还没有发送到客户端的头部信息
var contentType = response.getHeader('content-type');
5)response.headersSent 返回响应头是否已经发送
6)response.removeHeader( name ) 移除等待发送头部的某个键值对
7)response.sendDate 设置是否自动马上 Date 的头部信息,默认为 true。Http也要求响应头部中存在 Date 信息
8)response.setHeader( name, value ) 设置头部信息的键值对。若该键值和它的值已经存在,则把新值覆盖旧值。同时由该api设置的头部信息会被合并到 response.writeHead( )的信息中。
response.setHeader('Content-Type', 'text/html');
response.setHeader('Set-Cookie', ['type=ninja', 'name=asd']);
9)response.setTimeout( msecs, callback ) 设置套接字的超时时间。若也提供了callback函数,则相当于为response对象添加'timeout'监听器。若无监听'timeout'监听器,则套接字会在超时时自动销毁。
10)response.statusCode 设置http状态码。 response.statusCode = 404;
11)response.statusMessage 设置状态码对应的状态信息。若设置为'undefined',则自动使用标准的状态信息。
12)response.write( chunk [, encoding] [, callback ]) 该api能调用多次。当第一次调用时,它会发送缓存的头部信息和第一个相应体给客户端。第二次调用时,Node会认为你是要传输流式数据,并缓存到第一块相应体中。
13)response.writeContinue( ) 向客户端发送HTTP / 1.1 100 Continue消息,指示应该发送请求体。
14)response.writeHead( statusCode, [, statusMessage ] [, headers ]) 发送相应头到请求中。此api只能被调用一次,而且只能在response.end( ) 之前调用。若在该api之前调用response.setHeader( ),他们会被合并到response.writeHead( )已存在的头部键值对中。
var body = 'hello world';
response.writeHead(200, {
'Content-Length': Buffer.byteLength(body),
'Content-Type': 'text/plain' });
// returns content-type = text/plain
const server = http.createServer((req,res) => {
res.setHeader('Content-Type', 'text/html');
res.setHeader('X-Foo', 'bar');
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('ok');
});
http.InComingMessage
InComingMessage对象由http.server或者http.ClientRequest对象创建。它实现了可读流的接口,具有以下事件、方法和属性
1)Event: 'aborted' 当客户端中断请求和套接字关闭时触发
2)Event: 'close' 当底层的连接断开时触发,该事件在每个响应里只触发一次。
3)message.destroy( [error ]) 在接受到IncomingMessage的套接字上调用。
4)message.headers 返回请求/响应的头部信息对象。
// { 'user-agent': 'curl/7.22.0',
// host: '127.0.0.1:8000',
// accept: '*/*' }
console.log(request.headers);
5)message.httpVersion 返回Http版本。
6)message.method 返回请求的方法
7)message.rawHeaders 返回响应/请求的头部信息<Array>。
8)message.setTimeout( msecs, callback )
9)message.statusCode 返回状态码
10) message.statusMessage 返回状态信息
11)message.socket 返回与连接相关的套接字对象
12)message.url 返回请求的指定地址
http.METHODS
返回一组Http能支持解析的Http方法
http.STATUS_CODES
返回一组http状态码与默认信息的对象
httpCreateServer
返回一个新的http.Server实例
http.get
Node提供的一个便捷方式,method自动设为'GET',并自动调用req.end( )
http.get('http://nodejs.org/dist/index.json', (res) => {
const statusCode = res.statusCode;
const contentType = res.headers['content-type'];
// ...
})
http.blobalAgent
http.request
http.request( options [, callback ]) { } 其中option有以下这些选项:protocol 默认为'http';host 默认为 'localhost';hostname;family;port 默认为 80;localAddress;socketPath;method;path;headers;agent;Connection;timeout;等
var postData = querystring.stringify({
'msg' : 'Hello World!'
}); var options = {
hostname: 'www.google.com',
port: 80,
path: '/upload',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(postData)
}
}; var req = http.request(options, (res) => {
// ...
})
Node6.9.2 —— Http官网笔记整理的更多相关文章
- vue官网笔记
学习了vue后又重新过了一遍官网的教程,选择性地摘抄了一些自己觉得比较重要的知识点.以备后面查缺补漏用. 计算属性 计算属性mounted中,属性值函数将用作属性的getter函数.当函数中的依赖发生 ...
- 官网英文版学习——RabbitMQ学习笔记(十)RabbitMQ集群
在第二节我们进行了RabbitMQ的安装,现在我们就RabbitMQ进行集群的搭建进行学习,参考官网地址是:http://www.rabbitmq.com/clustering.html 首先我们来看 ...
- Android自动化学习笔记之Robotium:学习官网实例
---------------------------------------------------------------------------------------------------- ...
- Angular2发布思路(整理官网Deployment页面)
本文是按着ng2官网的高级内容“Deployment”的思路整理得出的,原文虽然在angular2的中文站下挂着,截止目前却还是英文版未翻译,笔者就在这里结合自己的理解给出原文的一点点整理.这是原文地 ...
- go语言,golang学习笔记1 官网下载安装,中文社区,开发工具LiteIDE
go语言,golang学习笔记1 官网下载安装,中文社区,开发工具LiteIDE Go语言是谷歌2009发布的专门针对多处理器系统应用程序的编程进行了优化,使用Go编译的程序可以媲美C或C++代码的速 ...
- 阅读Protobuf官网的一些笔记
阅读 Protobuf 官网的一些笔记 Protobuf API(The Protocol Buffer API) 每个字段都会有基本的 set_ get_ 方法 string类型的字段可以使用 mu ...
- [转]OpenTK学习笔记(1)-源码、官网地址
OpenTK源码下载地址:https://github.com/opentk/opentk OpenTK使用Nuget安装命令:OpenTK:Install-Package OpenTK -Versi ...
- 官网实例详解-目录和实例简介-keras学习笔记四
官网实例详解-目录和实例简介-keras学习笔记四 2018-06-11 10:36:18 wyx100 阅读数 4193更多 分类专栏: 人工智能 python 深度学习 keras 版权声明: ...
- 官网英文版学习——RabbitMQ学习笔记(一)认识RabbitMQ
鉴于目前中文的RabbitMQ教程很缺,本博主虽然买了一本rabbitMQ的书,遗憾的是该书的代码用的不是java语言,看起来也有些不爽,且网友们不同人学习所写不同,本博主看的有些地方不太理想,为此本 ...
随机推荐
- 谈谈iOS Animation
零.前言 这里没有太多的代码细节,只是探索iOS动画的基本概念,以及其抽象模型,数学基础等.我们学习一个知识的时候一般有两个部分,抽象部分和形象部分,抽象好比语言的语法,是规则,形象好比具体的句子,可 ...
- 基于 WebSocket 实现 WebGL 3D 拓扑图实时数据通讯同步(二)
我们上一篇<基于 WebSocket 实现 WebGL 3D 拓扑图实时数据通讯同步(一)>主要讲解了如何搭建一个实时数据通讯服务器,客户端与服务端是如何通讯的,相信通过上一篇的讲解,再配 ...
- JQuery Datatables Columns API 参数详细说明
---恢复内容开始--- Data Tables: http://datatables.NET/ Version: 1.10.0 Columns说明 虽然我们可以通过DOM直接获取DataTables ...
- JavaScript结构三层——思想快速介绍
本文版权归博客园和作者吴双本人所有,转载和爬虫请注明原文地址 http://www.cnblogs.com/tdws/,我是博客园蜗牛,我们共同进步. 今天讨论的是什么 如果你的工作中需要写JavaS ...
- JDBC_part2_DML以及预编译_编写DBUtil工具类
本文为博主辛苦总结,希望自己以后返回来看的时候理解更深刻,也希望可以起到帮助初学者的作用. 转载请注明 出自 : luogg的博客园 谢谢配合! jdbc day02 DML语法 比起插叙语句,没有R ...
- Servlet 服务器性能提高--->数据库请求频率控制(原创)
首先我要说下我实现这个功能接口涉及到的业务和实现的详细流程,然后会说此接口涉及到的相关技术,最后会贴出注释后的详细代码, 这个接口涉及到的是 app上咻一咻功能,咻一咻中奖的奖品一共有七类,其中四类是 ...
- 从零开始学 Java - Spring 集成 Memcached 缓存配置(一)
硬盘和内存的作用是什么 硬盘的作用毫无疑问我们大家都清楚,不就是用来存储数据文件的么?如照片.视频.各种文档或等等,肯定也有你喜欢的某位岛国老师的动作片,这个时候无论我们电脑是否关机重启它们永远在那里 ...
- 推荐书单(转自GITHUB)
Skip to content PersonalOpen sourceBusinessExplore Sign upSign in PricingBlogSupport This reposito ...
- 关于i++引出的线程不安全性的分析以及解决措施
Q:i++是线程安全的吗? A:如果是局部变量,那么i++是线程安全. 如果是全局变量,那么i++不是线程安全的. 理由:如果是局部变量,那么i++是线程安全:局部变量其他线程访问不到,所以根本不存在 ...
- Sqlserver中一直在用又经常被忽略的知识点一
已经有快2个月没有更新博客了,实在是因为最近发生了太多的事情,辞了工作,在湘雅医院待了一个多月,然后又新换了工作...... 在平时的工作中,Sqlserver中许多知识点是经常用到的,但是有时候我们 ...