HTTP的模块是nodejs最重要的模块(应该是),最近在看HTTP权威指南,重新过了一遍http协议和web客户端。再来看这个http。

HTTP构建于TCP之上,属于应用层协议,继承自tcp服务器(net模块),它能与多个客户端保持连接,由于基于事件驱动,并不为每个连接创建额外的进程或线程,所以能实现高并发;HTTP服务器与TCP服务器有区别的地方在于,在开启keepalive后,一个tcp会话可以用于多次请求和响应。TCP服务是以connection为单位进行服务,HTTP是以request为单位进行服务,HTTP模块就是将connection到request的过程进行了封装。

http模块将连接所用的套接字的读写抽象为serverRequest和serverResponse对象,他们分别对应请求和响应。在请求产生过程中,http模块拿到连接中的数据,调用二进制模块http_parser进行解析,解析玩报文的报头后,触发request事件,调用用户的业务逻辑。

HTTP的消息头通过对象表示
{ 'content-length': '123',
'content-type': 'text/plain',
'connection': 'keep-alive',
'host': 'mysite.com',
'accept': '*/*' }

http.STATUS_CODES//例如http.STATUS_CODES[404]==='Not Found';
http.createServer([requestListener]);//返回一个新的web服务器对象;

类http.Server这是一个包含下列事件的EventEmitter
事件'request'function(request,response){}
//每次收到一个请求时触发,每个链接又可能有多个请求;
//request是http.IncomingMessage的一个实例.response是http.ServerResponse的一个实例;
事件'connection' function(socket){}
//新的TCP流建立时触发。socket是一个net.Socket对象。通常用户无需处理改时间
事件'close'
事件'checkContinue'//每次收到Expect:100-continue的http请求时触发。如果未监听该事件,服务器会酌情发送100Continue响应
事件'connect' function(request,socket,head){}//每次客户端发起CONNECT请求时触发。如果未监听该事件,客户端发起CONNECT请求时连接会被关闭
//request是该http请求的参数;head是一个Buffer实例,隧道流的第一个包,可能为空
//这个世界被分发后,请求的套接字将不会有data事件监听器,你需要绑定一个监听器到data事件,处理套接字被发送到服务器的数据
事件'upgrade' function(request,socket,head){}//每当一个客户端请求http升级时触发;需要绑定data监听器
事件'clientError'function(exception,socket){}//客户端触发一个error事件,被转发到此;
server.listen(port,[hostname],[cb],[backlog],[callback])//开始在指定的主机名和端口接收连接
//积压量backlog为连接等待队列的的最大长度。
server.listen(path,[cb]);//启动一个unix套接字在所给路径path上监听连接;
server.close([cb])//仅在服务端接收新连接
server.maxHeadersCount//最大请求头目现在,默认1000个
server.setTimeout(msecs,cb);//设置超时值,若超时,分发’timeout‘事件,同时将套接字做参传入;
server.timeout//一个套接字被判为超时之时闲置的毫秒数;
类http.ServerResponse//这是一个由HTTP服务器内部创建的对象,他将做为2参传递到'request'事件中;实现了weitable Stream接口,是一个包含下列事件的EventEmitter
事件'close' function(){}//底层连接在response.end()或被调用或可以冲洗掉之前就被终结了。;
response.writeContinue()//发送一个HTTP/1.1 100 Continue消息至客户端,表明请求体可被发送;
response.writeHead(statusCode,[reasonPhrase],[headers])//向请求恢复响应头,statusCode是一个3位HTTP状态码;
//headers是响应头的内容。把人类可读的‘原因短句’作为第二个参数;
response.setTimeout(msecs,cb);
response.statusCode//使用默认headers时,这个属性决定headers更新时被传回客户端的http状态码;
response.setHeader(name,value)//为默认或已存在的头设置一条单独的头内容,如果已存在于将被送出的头重,将会覆盖其如果想设置更多的头,就会使用一个相同名字的字符串数组。
·response.setHeader("Set-Cookie", ["type=ninja", "language=javascript"]);
·response.setHeader("Content-Type","text/html");
response.headersSent//如果headers发送完毕为true,反正为false;
response.sendData//若为true,则当headers里没有Date值时自动生成Date并发送,默认true;
response.getHeader(name)//读取一个在队列中但还没有被发送只客户端的header
response.removeHeader(name)//取消一个在队列内等待发送的header
response.write(chunk,[encoding])//发送一个响应体的数据块,可能被调用多次以防继承部分响应体;
//chunk可以是字符串或缓存,若为字符串,2参表明如何将一个字符串编码为一个比特流。
response.addTrailers(headers)//这个方法添加HTTP尾随headers给响应;
//只有当数据块编码被用于响应时尾随才会被触发,如果不是,会被自动丢弃;
//如果触发尾随消息,HTTP要求一个报文头场列表和Trailer报头一起发送;
response.writeHead(200, { 'Content-Type': 'text/plain',
'Trailer': 'Content-MD5' });
response.write(fileData);
response.addTrailers({'Content-MD5': "7895bf4b8828b55ceaf47747b4bca667"});
response.end();
response.end([data],[encoding]);//当所有响应报头和报文被发送完成时,这个方法将信号发送给服务器,服务器会认为消息完成了,每次响应完成必须调用此;
http.request(options,cb);
//node维护几个连接每个服务器的HTTP请求,这个函数允许后台发布请求。
//options可以是一个对象或一个字符串。如果options是一个字符串,它将自动使用url.parse()解析;
host:请求发送到的服务器的域名或IP地址。默认为'localhost'。
hostname:用于支持url.parse()。hostname比host更好一些
port:远程服务器的端口。默认值为80。
localAddress:用于绑定网络连接的本地接口。
socketPath:Unix域套接字(使用host:port或socketPath)
method:指定HTTP请求方法的字符串。默认为'GET'。
path:请求路径。默认为'/'。如果有查询字符串,则需要包含。例如'/index.html?page=12'。请求路径包含非法字符时抛出异常。目前,只否决空格,不过在未来可能改变。
headers:包含请求头的对象。
auth:用于计算认证头的基本认证,即'user:password'
agent:控制Agent的行为。当使用了一个Agent的时候,请求将默认为Connection: keep-alive。可能的值为:
undefined(默认):在这个主机和端口上使用[全局Agent][]。

此例构造了一个http客户端,node模拟的客户端请求。

var options={
hostname:‘127.0.0.1’,
port:1334,
path:'/',
method:'GET'
}
var req=http.request(options,function(res){
console.log('STAUS: '+res.statusCode);
console.log('HRADERS: '+JSON.stringify(res.headers));
res.setEncoding(utf8);
res.on('data',function(chunk){
console.log(chunk);
})
})
req.end()

Agent对象:在Agent中显式使用passed。
false:在对Agent进行资源池的时候,选择停用连接,默认请求为:Connection: close。
keepAlive:{Boolean} 保持资源池周围的套接字在未来被用于其它请求。默认值为false
keepAliveMsecs:{Integer} 当使用HTTP KeepAlive的时候,通过正在保持活动的套接字发送TCP KeepAlive包的频繁程度。默认值为1000。仅当keepAlive被设置为true时才相关。
//http.request()返回一个http.ClientRequest类的实例。ClientRequest实例是一个可写流对象,如果需要用post请求上传一个文件的话,将其写入到ClientRequest对象;
http.get(options,cb)//与http.request()唯一区别是它设置的是get方法并自动调用req.end();

http.get("http://www.google.com/index.html", function(res) {
console.log("响应:" + res.statusCode);
}).on('error', function(e) {
console.log("错误:" + e.message);
});

类http.Agent

//用于把套接字做成资源池,用于http客户端请求;

http服务器默认的客户端代理对象http.globalAgent,它对每个服务器端创建的连接进行管理,默认情况下,对同一个服务器端发起的http请求最多创建5个链接,它的实质是一个连接池。

我们可以自行构造代理对象。

var agent=new http.Agent({
maxSockets:10
})
var options={
hostname:"127.0.0.1",
post:1334,
path:"/",
method:"GET",
agent:agent
};

也可以设置agent为false,就脱离连接池的管理,使请求不受并发的限制。

http Agent把客户端请求默认使用Connection:keep-alive。如果没有http请求在等待成为空闲的套接字,那么套接字将关闭。

当套接字触发了close事件或特殊的agentRemove事件的时候,套接字从agent资源池中移出。

如果你打算保持一个http请求长时间开启,并不希望它保持在资源池中,那么你可以按照下列代码:

http.get(options,function(res){
//..dosomething
}).on('socket',function(socket){
socket.emit('agentremove')
})
可用agent:false选择完全停用资源池;
http.get({
hostname:'localhost',
port:80,path:'/',agent:false,
},function(res){//..})

类http.ClientRequest

//该对象在内部创建,并由http.request()返回。他表示着一个正在处理的请求,其头部已经进入请求队列。

//该头部仍可以通过setHeader(name,value),getHeader(name),removeHeader(name)等api修改;

//为了获取响应对象,给请求对象添加一个'response'监听器。当接收到响应头时,请求对象会触发'response',该事件执行时有一个参数,参数为http.IncomingMessage的一个实例

在'response'事件期间,可以为响应对象添加监听器,尤其是'data事件'。

Event 'response'

function(res){}//当接收到请求的响应时触发,只被触发一次。response参数是http.http.IncomingMessage的一个实例;

事件'socket'//触发于一个套接字被赋予为这个请求的时候

事件'connect'//每次服务器使用connect方法响应一个请求时被触发。如果该事件未被监听,接收connect方法的客户端将关闭它们的连接;

socket.write('GET /HTTP/1.1\r\n'+'Host:www.google.com:80\r\n'+'Connection:close\r\n'+'\r\n');
socket.on('data',function(chunk){
console.log(chunk.toString());
})
socket.on('end',function(){
proxy.close();
})

事件'upgrade' function(response,socket,head){}

//每次服务器返回upgrade响应时触发。如果事件为被监听,客户端收到upgrade后将关闭连接

req.on('upgrade',function(res,socket,upgradeHead){
console.log('got upgrade!');
socket.end();
process.exit(0);
})

事件'continue'

//当服务器发送100 continue响应时触发,通常是因为请求保护Expect:100-contine,该指令表示客户端应发送请求体。

request.write(chunk,[encoding])

//发送一块请求体。调用多次。用户可以流式发送请求体至服务器--在这种情况下,创建请求时建议使用['Transfer-Encoding','chunked']当所有响应报头和报文被发送完成时,这个方法将信号发送给服务器,服务器会认为消息完成了,每次响应完成必须调用此;

request.end([data],[encoding])

//结束发送请求。

request.abort()//终止一个请求;

request.setTimeout(timeout,[cb])//一旦一个套接字被分配给该请求并且完成连接,socket.setTimeout()将被调用

request.setNoDelay([noDelay])//一旦一个套接字被分配到一个请求  同上

http.http.IncomingMessage; 一个IncomingMessage对象由http.server或者http.http.ClientRequest创建的。并作为第一参数分别传递给'request'和'response'事件。它也可以被用来访问应答的状态,头文件和数据。’

事件'close'表示在response.end()被掉用或强制刷新之前,底层的连接已经被终止了。

nodejs的某些api~(五) HTTP模块的更多相关文章

  1. nodejs入门API之net模块

    net常用API解析以及应用 手动解析HTTP请求头 基于网络模块net与文件模块fs搭建简易的node服务 net模块部分API参数详细解析 一.net常用API解析以及简单的应用 net模块的组成 ...

  2. NodeJS学习笔记之Connect中间件模块(一)

    NodeJS学习笔记之Connect中间件模块(一) http://www.jb51.net/article/60430.htm NodeJS学习笔记之Connect中间件模块(二) http://w ...

  3. python爬虫主要就是五个模块:爬虫启动入口模块,URL管理器存放已经爬虫的URL和待爬虫URL列表,html下载器,html解析器,html输出器 同时可以掌握到urllib2的使用、bs4(BeautifulSoup)页面解析器、re正则表达式、urlparse、python基础知识回顾(set集合操作)等相关内容。

    本次python爬虫百步百科,里面详细分析了爬虫的步骤,对每一步代码都有详细的注释说明,可通过本案例掌握python爬虫的特点: 1.爬虫调度入口(crawler_main.py) # coding: ...

  4. NodeJS笔记(二)- 修改模块默认保存路径

    参考:nodejs prefix(全局)和cache(缓存)windows下设置 假设nodejs根目录为“D:\nodejs” 如下所示,新建“node_cache”文件夹用来存放全局缓存 该路径下 ...

  5. vuejs目录结构启动项目安装nodejs命令,api配置信息思维导图版

    vuejs目录结构启动项目安装nodejs命令,api配置信息思维导图版 vuejs技术交流QQ群:458915921 有兴趣的可以加入 vuejs 目录结构 build build.js check ...

  6. 基于AOP和ThreadLocal实现的一个简单Http API日志记录模块

    Log4a 基于AOP和ThreadLocal实现的一个简单Http API日志记录模块 github地址 : https://github.com/EalenXie/log4a 在API每次被请求时 ...

  7. nodejs入门API之http模块

    HTTP上的一些API及应用 HTTP模块上的服务(server)与响应(response) HTTP模块上的消息(message) HTTP模块上的代理(agent)与请求(request) HTT ...

  8. nodejs的某些api~(三)net模块

    net模块和http模块是node最重要的两个模块,前者是基于TCP的封装,后者的本质也是TCP.他们通过 tcp通信,建立一个可以收发消息的web服务器.我在写的作品里面用的express也是封装的 ...

  9. nodejs入门API之url模块+querystring模块

    关于URL的一些基础内容 URL模块的API解析 URL的参数URLSearchParams类 querystring模块 一.关于URL的一些基础内容 1.1 定义: 在WWW上,每一信息资源都有统 ...

随机推荐

  1. spring boot中log4j冲突问题和解决办法

    Spring Boot中自带了log4j日志管理.写法应该是: private static final Logger logger = Logger.getLogger(XXX.class); 而不 ...

  2. [微软].net2.1 的兼容支持情况.

    dotnet core 现在看起来 不支持xp 不支持 win10 最早版本的 和 版本. 军工客户 如果还不升级 winxp的话 可能还是没法用(客户端运行时) 不过根据前段时间安装的国产linux ...

  3. 在阿里云上部署 Postfix

    Postfix 可以很方便的在一台机器上部署 smtp 服务,在 centos 上来说的话可以使用: sudo yum install postfix sudo systemctl enable po ...

  4. Unable to handle kernel paging request at virtual address

    1.Unable to handle kernel paging request at virtual address 00000000 =====>越出内核地址空间范围,原因是由于使用空NUL ...

  5. jenkins中通过execute shell启动的进程会被杀死的问题

    在jenkins中配置自动更新部署项目时,如果采取用execute shell启动/关闭tomcat,会发现可以进行关闭tomcat, 但是无法启动tomcat,虽然构建会显示执行成功,但是查看进程, ...

  6. mvn clean compile package install deploy

    (1) package 目的是打包,在pom中,如果是jar就会打包成jar,如果是war就会打包成war 在pom.xml中: <modelVersion></modelVersi ...

  7. spring 标签

    */ @Slf4j @Service public class RetryService { @Autowired private MqConfig mqConfig; /** * 如果网络连接失败, ...

  8. react & youtube

    react & youtube https://www.npmjs.com/package/react-youtube https://developers.google.com/youtub ...

  9. NPOI 上传Excel功能

    1.首先写一个Excel表格,第一行数据库类型(varchar.date.decimal).第二行数据库类型长度(100.12,4.时间日期为空)2.html 加按钮 { type: "bu ...

  10. 51nod-1445-变色DNA(最短路)

    题意:题目是说从0到n-1,我还是习惯从1到n,所以以下我都这么写,大概题意就是(i, j)==‘Y’表示可以从i颜色变成j颜色,然后问我们最少删除几个会影响结果的‘Y’,能到n这个颜色: 没有意义的 ...