1、实现“Hello World!”及相关API介绍html
使用 HTTP 服务器和客户端必须使用 require('http')node
Node.js 中的 HTTP 接口设计主要是为了支持 传统的很难使用的多特性的协议,尤为是大量的信息。接口没有缓冲整个接收和相应,用户可以使用流式数据。
linux
HTPP信息的头部是像一个对象那样描述的:
api
{ 'content-length': '123', 'content-type': 'text/plain', 'connection': 'keep-alive', 'host': 'mysite.com', 'accept': '*/*' }
http.createServer([requestListener])数组
Returns: <http.Server>浏览器
返回一个新的 http.Server 的实例
服务器
requestListener 是一个自动添加 'request'
的函数异步
server.listen([port][, hostname][, backlog][, callback])socket
开始接受指定的端口号(port)和主机名(hostname)之间的链接。tcp
参数类型:
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 做为 'listening'
事件的一个监听器, 是一个异步的回调函数
response.writeHead(statusCode[, statusMessage][, headers])
给请求消息发送一个响应头
statusCode Number 类型, 是一个三位数的 HTTP 状态码 好比:404
statusMessage String 类型,是可选的,主要是提升可读性
headers Object 类型, 是一个响应头,第二个参数是可选的
例如:
var body = 'hello world';response.writeHead(200, { 'Content-Length': Buffer.byteLength(body), 'Content-Type': 'text/plain' });
此方法在一个消息上只能调用一次,且必须在 response.end()
以前调用
response.end([data][, encoding][, callback])
这个方法是用来告诉服务器,全部的响应头和响应主体已经发送完毕,服务器就会知道这个消息已经完成了。每个响应消息都必须调用 response.end()
encoding
<String>
callback
<Function>
若是指定了 data ,就至关于在 response.end(callback) 以前调用了 response.write(data, encoding)
若是指定了 callback ,将在响应流结束以后调用
结合以上内容,咱们再来看一下经典的 Node.js 入门案例,在页面打印“Hello World”
基本的骨架:
//第一步: 引入 http 模块 var http = require('http'); //第二步:建立一个服务器(requestListener 是一个函数,里面有2个参数,一个请求消息,一个响应消息) var server = http.createServer(function(req, res){ }); //第三步:服务器监听本地的82端口 server.listen(8082, '127.0.0.1');
设置消息内容:
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(), 页面是渲染不出来的,由于服务器会一直处于等待状态,没人告诉它响应消息是否结束了
在 Node.js 三大特色详解 一文中,咱们了解到传统的 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 客户端。
2、HTTP 服务器
先回顾下“Hello World!”这个例子
//第一步: 引入 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端口
一、http.Server
http.Server 继承自 net.Server
而 net.Server是一个 EventEmitter
,主要用来建立一个 TCP或者本地服务器。
事实上,Node.js 中大部分模块都继承自 EventEmitter,包括fs、net等模块,这也是为何说 Node.js 基于事件驱动。http.Server 提供的事件以下:
request
客户端发出请求时触发,每一次链接可能会发出不少个请求(假如是持久链接的话)。提供两个参数request 和 response,是最经常使用的事件
request
<http.IncomingMessage>
response
<http.ServerResponse>
connection
当 TCP 创建链接时,触发此事件,提供一个参数 socket,是 net.socket 的实例
socket
<net.Socket>
close
当服务器关闭时,触发此事件。注意不是用户断开链接时
除此以外还有 checkContinue,upgrade,clientError 等事件,只有在实现复杂的 HTTP 服务器的时候才会用到。
在这些事件中,最经常使用的就是 request 事件,因此,http 提供了一个捷径:http.createServer( requestListener ),如咱们所知,功能就是建立一个 HTTP 服务器并将 requestListener 做为 request 事件的监听函数,
二、http.IncomingMessage --> request
http.IncomingMessage 是 HTTP 请求的信息,通常由 http.Server 的 request 事件发送,并做为第一个参数传递,http 请求通常包括 请求头部 和 请求主体。
其提供了三个事件用于控制请求体传输:
data: 当请求体数据到来时,触发该事件。该事件提供一个参数 chunk,表示接收到的数据。若是该事 件没有被监听,那么请求体将会被抛弃,该事件可能会被调用屡次
end:当请求体数据传输完成时,该事件被触发,此后将不会再有数据到来
close:用户当前请求结束时,该事件被触发。不一样于end,若是用户强制终止传输,也仍是调用 close
http.IncomingMessage 的属性以下:
三、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 相同,若是不调用此函数,客户端将用于处于等待状态(前面的案例提到过)
3、HTTP 客户端
http 模块提供了两个函数 http.request 和 http.get,功能是做为客户端向 HTTP 服务器发起请求
一、http.request(options, callback) 发起 HTTP 请求
接受两个参数,options表示请求的参数,能够是一个对象或字符串,若是是字符串的话,将自动调用 url.parse()
解析;
callback 是请求的回调函数,须要传递一个参数
options 经常使用的参数以下:
host:请求网站的域名或 IP 地址
port:请求网站的端口号,默认 80
method:请求方法,默认是 GET
path:请求的相对于根的路径,默认是“/”。QueryString 应该包含在其中,例如:/search?query=byvoid
headers:一个关联数组对象,为请求头的内容
http.request() 返回一个 http.ClientRequest
的实例
示例代码:
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 代码了
二、http.get(options, callback)
因为大多数的 GET 请求都没有主体,因此 Node.js 提供了这个简便的方法用于处理 GET 请求。
此方法是 http.request 的简化版,惟一的区别在于 http.get 自动将请求方法设为了 GET 请求,同时不须要手动调用 req.end()
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 代码
三、http.ClientRequest
http.ClientRequest 是由 http.request 或 http.get 返回产生的对象,表示一个已经产生并且正在进行中的 HTTP 请求。
它提供了一个 response 事件,即 http.request 或 http.get,第二个参数指定的回调函数的绑定对象。咱们能够显示地绑定这个事件的监听函数:
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 将会被调用。
四、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():从暂停的状态中恢复。