http模块内部封装了http服务器和客户端,因此Node.js不需要借助Apache、IIS、Nginx、Tomcat等传统HTTP服务器,就可以构建http服务器,亦可以用来做一些爬虫。下面简单介绍该模块的使用,其具体API,大家可以自行去nodejs官方文档查看。
1、http.Server服务器
使用http.createServer([requestListener])方法创建一个http服务器,该方法返回一个新的http.Server实例,如果指定了requestListener,则会自动添加request事件。http.Server继承于net.Server,故默认拥有很多的属性、方法和事件,如下图所示(只给出部分):
使用如下所示:
const http = require('http'); const server = http.createServer(); server.on('request', (req, res) => { res.writeHead(200, { 'content-type': 'text/plain' }); res.end('hello world'); }); server.on('listening', () => { console.log(`Server is lintening on ${server.address().address}:${server.address().port}`); }); server.listen(3000);
代码中的request事件监听的参数req,res分别是http.IncomingMessage,http.ServerResponse的实例,IncomingMessage对象是由 http.Server 或 http.ClientRequest 创建,并且被自动添加到'request' and 'response' 事件监听函数的第一个参数,是一个可读流,主要包括一些状态信息,请求信息,属性如下所示:
ServerResponse对象是HTTP server内部创建,并作为request事件监听函数的第二个参数,实现了可写流,决定返回给客户端的内容,属性如下所示:
创建一个http服务器,并监听3000端口,用浏览器打开:3000浏览,即可看到hello world。
我们还可以创建一个简易的路由,对用户的请求进行处理,如下所示:
//router.js module.exports = router; function router(req,res,pathname,handle){ if(typeof handle[pathname] === 'function'){ return handle[pathname](req,res); }else{ res.writeHead(200,{'Content-Type':'text/html'}); res.end('The request is not found!'); } } //handle.js const dns = require('dns'); const fs = require('fs'); const qs = require('querystring'); function showIndex(req,res){ ... } function lookup(req,res){ ... } exports['https://www.jb51.net/'] = showIndex; exports['/dnslookup'] = lookup;
2、http.ClientRequest客户端
该对象通过http.request()或http.get()方法创建,可以作为一个向服务器发起请求的客户端,该对象的属性(只列出部分)如下:
http.request(options[, callback])方法使用
参数options可以是一个对象或字符串,如果是字符串则会自动调用url.parse()进行解析,包涵以下属性(部分):
protocol,协议,默认为http:
host,主机地址
hostname,主机名
family,IP版本
port,端口
method,请求方法
path ,路径
headers ,请求头
timeout ,超时时间
callback会自动添加给reponse事件监听,返回值为http.ClientRequest,下面利用该知识写一个利用支付宝接口查询银行卡号所属银行,不过http换成了https,接口一致,代码如下:
const https = require('https'); const banknames = require('./bankname.js'); const btypes = { DC: '借记卡', CC: '信用卡' }; var baseUrl = 'https://ccdcapi.alipay.com/validateAndCacheCardInfo.json?_input_charset=utf-8&cardBinCheck=true&cardNo='; var cardNo = process.argv.slice(2)[0]; if (!/^\d{16,}$/.test(cardNo)) { console.log(`参数错误,请输入16位以上银行卡号。例如:node http-get.js 6228430120000000000`); process.exit(0); } baseUrl = baseUrl + cardNo; const client = https.get(baseUrl, (res) => { const status = res.statusCode; const type = res.headers['content-type']; let msg = ''; let data = ''; if (status !== 200) { msg = '发送请求失败 code:' + statusCode; } else if (!/^application\/json/.test(type)) { msg = '返回的数据格式不正确,应返回JSON'; } if (msg != '') { console.log(msg); process.exit(0); } res.setEncoding('utf8'); res.on('data', (chunk) => { data += chunk; }); res.on('end', () => { try { let bankObj = JSON.parse(data); dealBankObj(bankObj); } catch (e) { console.log(e.message); } }); }); client.on('error', (err) => { console.log(err.message); }); function dealBankObj(obj) { const bname = banknames[obj['bank']]; const btype = obj['cardType']; const cardId = obj['key']; console.log(`卡号:${cardNo}\r\n银行:${bname}\r\n类型:${btypes[btype]}`); }
bankname.js