博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Node.js 初识 HTTP 模块
阅读量:6842 次
发布时间:2019-06-26

本文共 7477 字,大约阅读时间需要 24 分钟。

一、实现“Hello World!”及相关API介绍


使用 HTTP 服务器和客户端必须使用 require('http')


Node.js 中的 HTTP 接口设计主要是为了支持 传统的很难使用的多特性的协议,尤其是大量的信息。接口没有缓冲整个接收和相应,用户可使用流式数据。


HTPP信息的头部是像一个对象那样描述的:

1
2
3
4
5
'content-length'
'123'
,
  
'content-type'
'text/plain'
,
  
'connection'
'keep-alive'
,
  
'host'
'mysite.com'
,
  
'accept'
'*/*' 
}


http.createServer([requestListener])

Returns: 

返回一个新的 http.Server 的实例

requestListener 是一个自动添加  的函数


server.listen([port][, hostname][, backlog][, callback])

开始接受指定的端口号(port)和主机名(hostname)之间的连接。


参数类型:

port:Number

hostname:String

backlog:Number

callback:Function

如果省略了 hostname,当IPV6可用时,服务器将连接任意的IPV6地址(::),或者是任意的IPV4地址 (0.0.0.0)

忽略 port 参数或者使用 0 作为端口号,如果想让操作系统随机分配一个端口号,可以在 'listening'

事件之后使用 server.address().port 来重新取回


如果想要监听 unix 套接字,可以用一个文件名来替换 port 和 hostname


backlog 是连接请求队列的最大长度,实际的长度将由你的 OS 通过系统调用设置来决定,比如 linux 上的 tcp_max_syn_backlog 和 somaxconn  。这个参数的默认值是511(不是512)


callback 作为  事件的一个监听器, 是一个异步的回调函数



response.writeHead(statusCode[, statusMessage][, headers])

给请求消息发送一个响应头


statusCode  Number 类型, 是一个三位数的 HTTP 状态码 比如:404

statusMessage  String 类型,是可选的,主要是提高可读性

headers  Object 类型, 是一个响应头,第二个参数是可选的


例如:

1
2
3
var 
body = 
'hello world'
;response.writeHead(200, {
  
'Content-Length'
: Buffer.byteLength(body),
  
'Content-Type'
'text/plain' 
});

此方法在一个消息上只能调用一次,且必须在  之前调用



response.end([data][, encoding][, callback])

这个方法是用来告诉服务器,所有的响应头和响应主体已经发送完毕,服务器就会知道这个消息已经完成了。每一个响应消息都必须调用 response.end()


  • data  | 

  • encoding 

  • callback 

如果指定了 data ,就相当于在 response.end(callback) 之前调用了 

如果指定了 callback ,将在响应流结束之后调用



结合以上内容,我们再来看一下经典的 Node.js 入门案例,在页面打印“Hello World”


基本的骨架:

1
2
3
4
5
6
7
8
9
10
//第一步: 引入 http 模块
var 
http = require(
'http'
);
 
//第二步:创建一个服务器(requestListener 是一个函数,里面有2个参数,一个请求消息,一个响应消息)
var 
server = http.createServer(
function
(req, res){
 
});
 
//第三步:服务器监听本地的82端口
server.listen(8082, 
'127.0.0.1'
);

设置消息内容:

1
2
3
4
5
6
7
8
9
10
var 
server = http.createServer(
function
(req, res){
    
//req -> request,表示请求; res -> response,表示响应
 
    
//设置响应头,第一个参数是3位数的HTTP状态码,第二个参数可选,第三个参数是一个对象,里面可存放合法的MIME类型
    
//MIME类型:文件类型是纯文本,字符集编码方式是 utf8
    
res.writeHead(200,{
'Content-Type'
'text/plain; charset=utf8'
});
    
//响应消息发送结束,如果指定了data参数,就相当于在 res.end() 之前添加了一个 res.end(data, encoding) 方法
    
//res.end('Hello World!', 'utf8');
    
res.end(
'Hello World!'
);
});

通过命令行工具挂起服务器,打开浏览器,在地址栏输入: 127.0.0.1:8082

同时,也可以打开控制台查看请求头部

值得注意的是,如果省略了 res.end(), 页面是渲染不出来的,因为服务器会一直处于等待状态,没人告诉它响应消息是否结束了


在    一文中,我们了解到传统的 HTTP服务器一般建立在 Apache、Nginx、IIS等服务器上,而 Node.js 并不需要,由于 Node.js 提供了 http 模块,自身就可以构建服务器(从上面的例子可以体会到)。


http 模块 是通过 C++实现的,性能非常可靠,其中,封装了一个 http 服务器 和一个简易的 http 客户端。http.Server 是一个基于事件的 http 服务器,http.request 则是一个 http 客户端工具,用于向 http 服务器发起请求


前面提到的 http.createServer( requestListener ) 方法中,requestListener 是一个回调函数,函数有2个参数 request 和 response,request 是 http.IncomingMessage 对象的实例,response 是  http.ServerResponse 对象的实例。下面分别来学习 HTTP 服务器 和 HTTP 客户端。



二、HTTP 服务器


先回顾下“Hello World!”这个例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//第一步: 引入 http 模块
var 
http = require(
'http'
);
 
//第二步:创建一个服务器(requestListener 是一个函数,里面有2个参数,一个请求消息,一个响应消息)
var 
server = http.createServer(
function
(req, res){
    
//req -> request,表示请求; res -> response,表示响应
 
    
//设置响应头,第一个参数是3位数的HTTP状态码,第二个参数可选,第三个参数是一个对象,里面可存放合法的MIME类型
    
//MIME类型:文件类型是纯文本,字符集编码方式是 utf8
    
res.writeHead(200,{
'Content-Type'
'text/plain; charset=utf8'
});
    
//响应消息发送结束,如果指定了data参数,就相当于在 res.end() 之前添加了一个 res.end(data, encoding) 方法
    
//res.end('Hello World!', 'utf8');
    
res.end(
'Hello World!'
);
});
 
//第三步:服务器监听本地的82端口
server.listen(8082, 
'127.0.0.1'
);

基本的结构是直接创建一个 http 对象,然后创建一个 http 对象的实例 server,并为其监听82端口


1、http.Server

http.Server 继承自  而 net.Server是一个 ,主要用来创建一个 TCP或者本地服务器。

事实上,Node.js 中大部分模块都继承自 EventEmitter,包括fs、net等模块,这也是为什么说 Node.js 基于事件驱动。http.Server 提供的事件如下:

request

客户端发出请求时触发,每一次连接可能会发出很多个请求(假如是持久连接的话)。提供两个参数request 和 response,是最常用的事件

  • request 

  • response 

connection

当 TCP 建立连接时,触发此事件,提供一个参数 socket,是 net.socket 的实例

  • socket 

close

当服务器关闭时,触发此事件。注意不是用户断开连接时

除此之外还有 checkContinue,upgrade,clientError 等事件,只有在实现复杂的 HTTP 服务器的时候才会用到。


在这些事件中,最常用的就是 request 事件,所以,http 提供了一个捷径:http.createServer( requestListener ),如我们所知,功能就是创建一个 HTTP 服务器并将 requestListener 作为 request 事件的监听函数,



2、http.IncomingMessage  --> request

http.IncomingMessage 是 HTTP 请求的信息,一般由 http.Server 的 request 事件发送,并作为第一个参数传递,http 请求一般包括 请求头部 和 请求主体。


其提供了三个事件用于控制请求体传输:

data: 当请求体数据到来时,触发该事件。该事件提供一个参数 chunk,表示接收到的数据。如果该事            件没有被监听,那么请求体将会被抛弃,该事件可能会被调用多次


end:当请求体数据传输完成时,该事件被触发,此后将不会再有数据到来


close:用户当前请求结束时,该事件被触发。不同于end,如果用户强制终止传输,也还是调用 close


http.IncomingMessage 的属性如下:


3、http.ServerResponse   ---> response

http.ServerResponse 是返回给客户端的信息,决定了用户最终能看到的结果。它是由 http.Server 的 request 事件发送的,作为第二个参数传递,一般简称为 response 或 res


http.ServerResponse 有三个重要的成员函数,用于返回响应头、响应内容以及结束请求(上面已经介绍过,这里再复习一次)


response.writeHead(statusCode[, statusMessage][, headers]):  向请求的客户端发送响应头

statusCode 是 HTTP状态码,常用的比如 200(请求成功),404(未找到)

headers 是一个类似关联数组的对象,表示响应头的每个属性


此函数在一个请求内最多只能调用一次,如果不调用,则会自动生成一个响应头


response.write(data, [encoding]): 向请求的客户端发送响应内容

data 是一个 Buffer 或字符串,表示要发送的内容。如果data 是字符串,那么需要指定 encoding 来说明它的编码方式,默认是 utf-8。在 response.end 调用之前,response.write 可以被多次调用


response.end([data], [encoding]): 结束响应

告知客户端所有发送已经完成,当所有要返回的内容都发送完毕的时候,该函数必须被调用一次。

此函数接受两个可选参数,意义和 response.write 相同,如果不调用此函数,客户端将用于处于等待状态(前面的案例提到过)




三、HTTP 客户端


http 模块提供了两个函数 http.request 和 http.get,功能是作为客户端向 HTTP 服务器发起请求


1、http.request(options, callback)  发起 HTTP 请求

接受两个参数,options表示请求的参数,可以是一个对象或字符串,如果是字符串的话,将自动调用       解析;

callback 是请求的回调函数,需要传递一个参数


options 常用的参数如下:

host:请求网站的域名或 IP 地址

port:请求网站的端口号,默认 80

method:请求方法,默认是 GET

path:请求的相对于根的路径,默认是“/”。QueryString 应该包含在其中,例如:/search?query=byvoid

headers:一个关联数组对象,为请求头的内容


http.request() 返回一个  的实例


示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var 
http=require(
"http"
);
 
var 
options={
    
hostname:
"www.12306.cn"
,
    
port:80
};
 
var 
req=http.request(options,
function
(res){
    
res.setEncoding(
"utf-8"
);
    
res.on(
"data"
,
function
(chunk){
        
console.log(chunk.toString())
    
});
    
console.log(res.statusCode);
});
req.on(
"error"
,
function
(err){
    
console.log(err.message);
});
req.end();

我们运行这段代码,就可以在控制台中看到 12036 的 HTML 代码了


2、http.get(options, callback) 

由于大多数的 GET 请求都没有主体,所以 Node.js 提供了这个简便的方法用于处理 GET 请求。

此方法是 http.request 的简化版,唯一的区别在于 http.get 自动将请求方法设为了 GET 请求,同时不需要手动调用 req.end()


1
2
3
4
5
6
7
var 
http = require(
'http'
);
http.get({host: 
'www.12306.cn'
}, 
function
(res) {
    
res.setEncoding(
'utf8'
);
    
res.on(
'data'
function 
(data) {
        
console.log(data);
    
});
});

运行这段代码,一样可以在控制台得到 12036 的 HTML 代码



3、http.ClientRequest

http.ClientRequest 是由 http.request 或 http.get 返回产生的对象,表示一个已经产生而且正在进行中的 HTTP 请求。

它提供了一个 response 事件,即 http.request 或 http.get,第二个参数指定的回调函数的绑定对象。我们可以显示地绑定这个事件的监听函数:


1
2
3
4
5
6
7
8
var 
http = require(
'http'
);
var 
req = http.get({host: 
'www.12306.cn'
});
req.on(
'response'
function
(res) {
    
res.setEncoding(
'utf8'
);
    
res.on(
'data'
function 
(data) {
        
console.log(data);
    
});
});

运行这段代码,一样可以在控制台得到 12036 的 HTML 代码


http.ClientRequest 像 http.ServerResponse 一样也提供了 write 和 end 函数,用于向服务器发送请求体,通常用于 POST、PUT 等操作。所有写结束以后必须调用 end 函数以通知服务器,否则请求无效。


http.ClientRequest 还提供了以下函数。

request.abort():终止正在发送的请求。

request.setTimeout(timeout, [callback]):设置请求超时时间,timeout 为毫秒数。当请求超时以后,callback 将会被调用。


4、http.ClientResponse

http.ClientResponse 与 http.ServerRequest 相似,提供了三个事件 data、end和 close,分别在数据到达、传输结束和连接结束时触发,其中 data 事件传递一个参数chunk,表示接收到的数据。


http.ClientResponse 也提供了一些属性,用于表示请求的结果状态


http.ClientResponse 还提供了以下几个特殊的函数。


response.setEncoding([encoding]):设置默认的编码,当 data 事件被触发时,数据将会以 encoding 编码。默认值是 null,即不编码,以 Buffer 的形式存储。常用编码为 utf8。


response.pause():暂停接收数据和发送事件,方便实现下载功能。


response.resume():从暂停的状态中恢复。

本文转自   frwupeng517   51CTO博客,原文链接:
http://blog.51cto.com/dapengtalk/1889787

转载地址:http://ewcul.baihongyu.com/

你可能感兴趣的文章
磁盘配额满与用户权限的更改
查看>>
ORACLE 数据类型
查看>>
KeyMob移动广告聚合平台为开发者提供最全面的保障
查看>>
钱sir 高数:一元函数积分学
查看>>
修改Windows server 2008远程桌面连接数量
查看>>
Excel文件导入异常-输入流无法识别
查看>>
我的友情链接
查看>>
CentOS6.4下YUM安装MySQL和JDK和Tomcat
查看>>
LVS解析及NAT、DR模型配置详解
查看>>
上期ctp期货API android 客户端
查看>>
puppet实战(一):文件同步+更改文件属性
查看>>
最简单的git部署方案
查看>>
js获取url参数值
查看>>
让MAC的终端显示颜色
查看>>
android开发-----message
查看>>
SVN分支/合并原理及最佳实践 (很实用,很不错哦)
查看>>
Hyper-V 3.0功能部署PART 8:计划故障转移
查看>>
Android--Button,ImageButton组件
查看>>
介绍MyBatis代码生成网站(六) --- SQL方法的选择
查看>>
2015年4月9日 大师 ▪ 计 (第四季) | VMware 技术支持日 上海站
查看>>