第二章 常用模块(二)
HTTP服务
HTTP模块
是Node的核心模块,主要是提供一系列用于网络传输的API,这些API大都位于比较底层的位置,可以让开发者自由地控制整个HTTP传输过程。
创建HTTP服务器
通常使用createServer
方法创建HTTP服务器,该方法返回一个http.server实例
。
var http = require("http")
var server = http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end("Hello Node!")
});
server.listen(3000);
处理HTTP请求
- method, URL和header
处理HTTP请求时,先要获取请求的URL、method等信息,这些相关信息都封装在一个对象(前面的req
)中,该对象是IncomingMessage
的实例。
var method = req.method;
// method通常为get、post、put、delete、update
var url = req.url;
- header
header
是一个JSON
对象,可以对属性名进行单独索引:
var headers = req.headers;
var userAgent = headers['user-agent'];
- request body
Node
使用stream
来处理HTTP请求体,这个stream
注册了data
和end
事件。
var body = [];
request.on('data', function(chunk) {
body.push(chunk);
}).on('end', function() {
body = Buffer.concat(body).toString();
});
Response 对象
- 设置
statusCode
在Node中如果开发者不手动设置,那么状态码默认为200
. - 设置response header
通过setHeader
方法可以设置response
的头部信息,setHeader只能设置单个属性的内容
response.writeHead
writeHead方法用于定义HTTP响应头,包括状态码等一系列属性。
response.setHeader('Content-Type', 'application/json');
response.setHeader('X-Powered-By', 'bacon');
- response body
response
可以直接调用write方法写入,完成后调用end方法将该stream发送到客户端。也可以将response body
作为end方法的参数进行返回。 - response.end
end方法
在每个HTTP请求的最后都会被调用。end方法支持一个字符串或者Buffer作为参数,可以指定HTTP请求的最后返回的数据。
上传数据
- 提交表单
content-type: application/x-www-form-urlencoded
- 使用post上传文件
content-type: multipart/form-data
HTTP客户端服务
HTTP模块
除了可以在服务器处理客户端请求外,还可以作为客户端向服务端发起请求。
创建代理服务器
代理服务器
相当于在客户端和目标服务器之间建立一个中转,可以用来缓存文件、过滤广告、限制员工访问社交网站等。
反向代理
:如果一个代理服务器可以代理外部的访问来访问内部网络,这种代理方式就被称为方向代理。(CDN就是反向代理的例子)
TCP服务
TCP和Socket
Socket
是对TCP协议的一种封装方式,Socket
本身并不是协议,而是一个编程接口,在接口上定义了一些基础方法,例如accept、listen、write等,通过socket接口预定义的方法来解析使用TCP协议传输的数据流。
创建TCP服务器
Node中有三种Socket
,分别对应TCP
、UDP
以及UNIX Socket
,对应代码都位于Net模块中,包含了Server类、Socket类以及一些预定义的方法。
更安全的传输方式——SSL
SSL
(Secure Sockets Layer,安全套接层)协议及TLS
(Transport Layer Security,传输层安全)协议是为网络通信提供安全及数据完整性的一种安全协议。
对称加密与非对称加密
对称密钥加密
(私钥加密、会话密钥加密算法)即信息的发送方和接收方使用同个密钥去加密和解密数据。优势是加/解密速度快,适合对大数据量
进行加密,但密钥管理困难。
非对称密钥加密
(公钥密钥加密),它需要使用不同的密钥来分别完成加密和解密操作,信息发送者用公开密钥去加密,而信息接收者则用私用密钥去解密。公钥机制灵活,但是加密和解密速度却比对称密钥加密慢
很多。
HTTPS的缺点
HTTPS的缺点
在于比普通的HTTP链接要慢。
WebSocket
WebSocket
同样是基于TCP协议的应用层协议,为了弥补HTTP协议的无持久化和无状态等缺陷而诞生的。
WebSocket
提供了客户端和服务器之间全双工的通信机制,可以由服务器主动发起向浏览器的数据传输。
WebSocket
的请求头中,Connection
字段必须设置为Upgrade
,表示客户端希望链接升级。
Upgrade
字段必须设置WebSocket
,表示希望升级到WebSocket协议。
Stream
Stream
模块为Node操作流式数据提供了支持。
Stream的种类
四种基础的stream类型:
Readable
:可读流Writable
:可写流Duplex
:即可读,又可写Transform
:操作写入的数据,然后读取结果。
ReadLine
模块提供了按行读取Stream中数据的功能。
Events
事件和监听器
Node程序中的对象会产生一系列的事件,它们被称为事件触发器
,所有能触发事件的对象都是EventEmitter
类的实例。
用户可以注册多个同名事件,并且都会被触发。使用eventNames
方法获取当前的emitter
一共注册哪些事件时,同名event只会输出一个。
处理error事件
可以让uncaughtException
事件作为最后一道防线来捕获异常。(不提倡
)
多进程服务
child_process
模块用来提供多进程的支持,包括了很多创建子进程的方法,包括fork、spawn、exec、execFile等。
spawn
方法会使用指定的command来生成一个新进程,执行完对应的command后子进程自动退出,可以通过监听事件来获得命令执行的结果。fork
相当于在命令行下调用node xx.js,并且父进程和子进程之间可以通过process.send方法来进行通信。execfile
和spawn
在形式上主要区别在于execfile
提供了一个回调函数,通过这个回调函数可以获得子进程的标准输出/错误流。
Cluster
Cluster
模块可以看作是做了封装的child_process
模块,显著优点是可以共享同一个socket
连接,这代表可以使用Cluster
模块实现简单的负载均衡。
Process对象
每个Node进程都有独立的process对象,该对象中存储了当前进程的环境变量,也定义了一些事件。
Timer
常用API
在Node中,setTimeout
和setInterval
属于Timeout
类,调用对应的方法后都会返回对应的对象。Node还提出了新的setImmediate
方法。
定时器中的this
在Node中,setTimeout
和setInterval
的this
会指向timeout
类