Node之HTTPS客户端
向其他网站请求数据
在Node.js中,也可以很轻松地向任何网站发送请求并读取该网站的响应数据。在http模块中,可以使用request方法向其他网站请求数据。
var req=http.request(options,callback)
- options:为一个对象或字符串,用于指定请求的目标URL地址,如果参数值为一个字符串,将自动使用url模块中的parse方法转换为一个对象。在options参数值对象或使用parse方法转换后的对象中,可以指定的属性及属性值如下
- host:用于指定域名或目标主机的IP地址,默认属性值为“localhost”。
- hostname:用于指定域名或目标主机的IP地址,默认属性值为“localhost”。如果hostname属性值与host属性值都被指定,优先使用hostname属性值。
- port:用于指定目标服务器用于HTTP客户端连接的端口号。
- localAddress:用于指定专用于网络连接的本地接口。
- socketPath:用于指定目标Unix域端口。
- method:用于指定HTTP请求方式,默认属性值为“GET”。
- path:用于指定请求路径及查询字符串,默认属性值为“/”。
- headers:用于指定客户端请求头对象。
- auth:用于指定认证信息部分,例如“user:password”。
- agent:用于指定HTTP代理。在Node.js中,使用http.Agent类代表一个HTTP代理。所谓HTTP代理,就是一个代表通过HTTP向其他网站请求数据的浏览器或者代理服务器。在Node.js中,HTTP代理默认在请求数据时使用keep-alive连接,同时使用一个全局的http.Agent对象来实现所有HTTP客户端请求。不使用agent属性值时,默认使用该全局http.Agent对象。可以为agent属性值显式指定一个http.Agent对象(即用户代理),也可以通过将agent属性值指定为false的方法从连接池中自动挑选一个当前连接状态为关闭的http.Agent对象(即用户代理)。
- callback:指定当获取到目标网站所返回的响应流时调用的回调函数。request方法返回一个http.ClientRequest对象,代表一个客户端请求。
function (response) { //回调函数代码略 }
向目标网站发送数据
在使用了request方法后,可以使用http.ClientRequest对象的write方法向目标网站发送数据
request.write(chunk,[encoding])
结束请求
request.end([chunk],[encoding])
完整请求示例
var http = require('http');
var options = {
hostname: 'www.microsoft.com',
port: 80,
path: '/',
method: 'GET'
};
var req = http.request(options,function(res) {
console.log('状态码: ' + res.statusCode);
console.log('响应头: ' + JSON.stringify(res.headers));
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log('响应内容: '+chunk);
});
});
req.end();
终止请求
可以使用http.ClientRequest对象的abort方法终止本次请求
request.abort
设置请求端口超时时间
request.setTimeout(timeout,[callback])
制作代理服务器
示例:
var http=require('http');
var url=require('url');
var server = http.createServer(function(sreq, sres) {
var url_parts = url.parse(sreq.url);
var opts = {
host: 'www.amazon.cn',
port: 80,
path: url_parts.pathname,
headers: sreq.headers
};
var creq = http.get(opts, function(cres) {
sres.writeHead(cres.statusCode, cres.headers);
cres.pipe(sres);
});
sreq.pipe(creq);
});
server.listen(1337, '127.0.0.1');
创建HTTPS服务器与客户端
在Node.js中,提供了一个https模块,专用于创建HTTPS服务器与客户端。
HTTPS服务器与HTTP服务器的区别
- HTTPS服务器使用HTTPS协议,而HTTP服务器使用HTTP协议。
- HTTPS服务器需要向证书授证(Certificate Authority)中心申请证书,一般免费证书很少,需要交费。在少许对客户端有要求的情况下,也会要求客户端使用证书。
- HTTP服务器与客户端之间传输的是明文数据,而HTTPS服务器与客户端之间传输的是经过SSL安全加密后的密文数据。
- HTTP服务器通常使用80端口或8080端口,而HTTPS服务器使用的是443端口。
创建HTTPS服务器
在创建HTTPS服务器之前,服务器端首先需要创建公钥、私钥及证书,步骤如下
- 创建私钥。可以使用openssl工具创建私钥
openssl genrsa -out privatekey.pem 1024
- 创建证书签名请求(Certificate Signing Request)文件
openssl req -new -key privatekey.pem -out certrequest.csr
- 获取证书。证书应该是一个经过证书授证中心签名的文件,该证书文件内包含了服务器端提供的公钥以及证书的颁发机构等信息,可以使用openssl工具创建一个学习或测试用的证书
x509参数表示该证书符合国际电信联盟制定的数字证书标准。openssl x509 -req -in certrequest.csr -signkey privatekey.pem -out certificate.pem
在客户端与服务器端建立连接后,将首先确认证书的合法性。如果在服务器中使用学习或测试用证书,使用浏览器访问该服务器时,浏览器中将显示一个警告信息,警告用户该证书不是一个经过证书授证中心签名的证书。
在具备了证书文件之后,可以使用该证书文件创建一个pfx文件。所谓pfx文件,是指该文件内容必须符合公钥加密技术12号标准(Public Key CryptographyStandards#12,PKCS#12)为存储和传输用户或服务器私钥、公钥和证书而指定的
格式。
在openssl工具中,可以使用如下所示的命令创建pfx文件。
openssl pkcs12 -export -in certificate.pem -inkey privatekey.pem -out certificate.pfx
在这些文件(其中pfx文件为可选用文件)具备了之后,可以使用https模块中的createServer方法创建一个HTTPS服务器
https.createServer(options,[requestListener])
- options:为一个对象,用于指定创建HTTPS服务器时可以使用的各种选项,在该对象中可以使用的属性及属性值
- pfx:属性值为一个字符串或一个Buffer对象,用于指定从pfx文件读取出的私钥、公钥以及证书。使用该属性值不需要指定key属性值、cert属性值以及ca属性值。
- key:属性值为一个字符串或一个Buffer对象,用于指定从后缀名为pem的私钥文件中读取出来的私钥。该属性值为必须指定属性值,除非指定了pfx属性值。
- passphrase:属性值为一个字符串,用于为私钥文件或pfx文件指定密码。
- cert:属性值为一个字符串或一个Buffer对象,用于指定从后缀名为pem的文件中读取出来的公钥。该属性值为必须指定属性值,除非指定了pfx属性值。
- ca:属性值为一个字符串数组或一个Buffer对象数组,用于指定一组证书,默认属性值为几个著名的证书授证中心,例如VerlSign。
- crl:属性值为一个字符串或字符串数组,用于指定证书吊销列表。
- ciphers:属性值为一个字符串值,用于描述需要使用或取消使用的密码。为了阻挡BEAST攻击,推荐将ciphers属性与honorCipherOrder属性结合使用,以指定非CBC(Cipher-block chaining,密码分组链接)模式的密码的优先级,默认属性值为AES128-GCM-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH。
- handshakeTimeout:属性值为一个整数,用于指定在多少秒内如果没有完成客户端与服务器之间的握手,则放弃本次连接。默认属性值为120(秒)。当在指定时间内没有完成握手时,将触发HTTPS服务器的clientError事件。
- honorCipherOrder:属性值为一个布尔值。当属性值指定为true时,服务器将密码列表发送给客户端,由客户端选择密码。尽管该属性值默认为false,但仍推荐将该属性值指定为true,以阻止BEAST攻击。
- requestCert:属性值为一个布尔值。当属性值指定为true时,服务器在确认连接时要求客户端提供证书。默认属性值为false。
- rejectUnauthorized:属性值为一个布尔值。如果属性值为true,那么服务器拒绝任何不能提供服务器端所要求的证书的客户端。只有当requestCert属性值指定为true时,该属性值才有效。默认属性值为false。
- NPNProtocols:属性值为一个数组或一个Buffer对象,用于指定服务器端所需使用的NPN协议(这些协议应该按照其优先级排序)。NPN(Next Protocol Negotiation)协议是一种用于指定服务器可以使用多种协议(包括HTTP、SPDY协议等)的协议。
- sessionIdContext:属性值为一个字符串,用于指定服务器端session的唯一标识符。如果requestCert属性值指定为true,那么默认属性值为一个MD5散列值。如果requestCert属性值指定为false,不提供默认属性值。
- requestListener:为一个回调函数,用于指定当服务器端接收到客户端请求时所需执行的处理
function (request,response) { //回调函数代码略 }
在创建了HTTPS服务器之后,我们需要指定该服务器所要监听的地址(可以为一个IP地址,也可以为一个主机名)及端口,这时,我们可以使用该HTTPS服务器的listen方法
server.listen(port,[host],[backlog],[callback])
关闭服务器
server.close();
创建HTTPS客户端
在https模块中,可以使用request方法向其他使用HTTPS协议的网站请求数据。
var req=https.request(options,callback)
- options:值为一个对象或字符串,用于指定请求的目标URL地址,如果该参数值为一个字符串,将自动使用url模块中的parse方法转换为一个对象。在options参数值对象或使用parse方法转换后
的对象中,可以指定的属性及属性值- host:用于指定域名或目标主机的IP地址,默认属性值为“localhost”。
- hostname:指定域名或目标主机的IP地址,默认属性值为“localhost”。如果hostname属性值与host属性值都被指定,优先使用hostname属性值。
- port:指定目标服务器用于HTTP客户端连接的端口号,默认属性值为443。
- method:用于指定HTTP请求方式,默认属性值为“GET”。
- path:用于指定请求路径及查询字符串,默认属性值为“/”。
- headers:用于指定客户端请求头对象
- auth:用于指定认证信息部分,例如“user:password”。
- agent:用于指定用户代理。在Node.js中,使用https.Agent类代表一个用户代理。在Node.js中,用户代理默认在请求数据时使用keep-alive连接,同时使用一个全局的https.Agent对象来实现所有HTTPS客户端请求。不使用agent属性值时,默认使用该全局https.Agent对象。可以为agent属性值显式指定一个https.Agent对象(即用户代理),也可以通过将agent属性值指定为false的方法从连接池中自动挑选一个当前连接状态为关闭的https.Agent对象(即用户代理)。
当在options参数值对象中使用如下所示的属性及属性值时,不能使用全局https.Agent对象。
- pfx:属性值为一个字符串或一个Buffer对象,用于指定从pfx文件读取出的私钥、公钥及证书。使用该属性值不需要指定key属性值、cert属性值及ca属性值。
- key:属性值为一个字符串或一个Buffer对象,用于指定从后缀名为pem的私钥文件中读取出来的私钥。该属性值为必须指定属性值,除非指定了pfx属性值。
- passphrase:属性值为一个字符串,用于为私钥文件或pfx文件指定密码。
- cert:属性值为一个字符串或一个Buffer对象,用于指定从后缀名为pem的文件中读取出来的符合X509标准的公钥。该属性值为必须指定属性值,除非指定了pfx属性值。
- ca:属性值为一个字符串数组或一个Buffer对象数组,用于指定一组证书。
- ciphers:属性值为一个字符串值,用于描述需要使用或取消使用的密码。
- rejectUnauthorized:属性值为一个布尔值。如果属性值为true,服务器在客户端建立连接后,返回响应前首先验证客户端提交的证书,如果验证失败,触发客户端请求对象的error事件。