NodeJS与外部源交互
概述
NodeJS中的HTTP服务的一个常见用途是访问外部系统获得的数据来满足客户端的的请求。
在这个例子中连接到API。为了保持例子简单性,来自响应数据以原始格式被推送到游览器。
思路
同时接受GET和POST请求的Web服务的实现。对于GET请求,则返回一个带有一个表单的网页,它允许用户提交一个电影名字。然后在POST请求中,名称被访问,且NodeJSWeb客户端启动远程连接到API检索信息。之后这些信息连同原来的网页表单被一起返回到服务器。
本实例与前一示例之间的最大区别在于,Web服务器还实现了一个本地Web客户端连接到外部服务,并获得数据,已完成响应
GetWeather()函数实现对API的客户端请求。然API后在parseweather()请求处理程序读取来自API的响应并把数据传递到第sendResponse()函数,它完成响应,并且将其返回给客户端。
清单
/**
* @description TODO
* @author suiyue
* @date 2019/9/2 9:38
*/
var http = require('http');
var url = require('url');
var qstring = require('querystring');
const iconv = require("iconv-lite");
/**
* 完成响应。将其数据返回给客户端
* @param weatherData
* @param res
*/
function sendResponse(weatherData,res) {
var page = '<html><head><title>External Example</title>>' +
'<meta charset="utf-8"/></head>' +
'<body><form method="post">City:<input name="city"><br><input type="submit" value="Get Weather"></form>';
if(weatherData) {
page += '<h1>Weather Info</h1><p>' + weatherData + '</p> ';
}
page += '</body></html>';
//console.log(page);
res.end(page);
}
/**
* 读取响应数据,传给sendResponse
* @param weatherResponse
* @param res
*/
function parseWeather(weatherResponse,res) {
const chunks = [];
var weatherData = '';
weatherResponse.on('data', function (chunk) {
chunks.push(chunk);
});
weatherResponse.on('end', function () {
// 合并数组生成 buff 对象
var buff = Buffer.concat(chunks), headers = res.headers;
// 从响应头中提取 charset
//var charset = headers['content-type'].match(/(?:charset=)(\w+)/)[1] || 'gbk';
// 转编码,保持跟响应一致
weatherData = iconv.decode(buff,'gbk');
sendResponse(weatherData, res);
});
}
/**
* web服务 post 实现对API的客户端请求
* @param city
* @param res
*/
function getWeather(city,res) {
var options = {
host: 'videos.yizhansou.com',
// port: '8080',
path:'/search?kw='+city
};
http.request(options, function (weatherResponse) {
parseWeather(weatherResponse, res);
}).end();
}
/**
* 创建请求
*/
http.createServer(function (req, res) {
// res.writeHeader(200, {'Content-Type' : 'text/html;charset:utf-8'
// });
//res.write('<head><meta charset="gbk"/></head>');
if(req.method=="POST"){
var reqData = '';
req.on('data', function (chunk) {
reqData += chunk;
console.log(reqData);
});
req.on('end',function(){
var postParams = qstring.parse(reqData);
//console.log(postParams);
console.log(postParams.city);
//console.log(res);
getWeather(postParams.city, res);
});
}else{
sendResponse(null, res);
}
}).listen(8080);
结果
推广
创建HTTPS客户端
几乎和http客户端一样,但HTTPS有额外的重要选项,是key,cert(证书)和agent(代理)
key选项指定用于SSL的私钥,cert值指定使用的X509公钥。全局代理不支持https需要的选项,所以你需要通过代理设置为null来禁用代理
var options = {
host: 'encrypted.myusite.com',
port: '443',
path: '/',
method:'GET',
key: fs.readFileSync('test/keys/clent.pem'),
cert: fs.readFileSync('test/keys/clent.crt'),
agent:false
};
http.request(options, function (weatherResponse) {
parseWeather(weatherResponse, res);
}).end();
创建HTTPS服务器
创建一个https服务器,还是要key,cert
var options = {
key: fs.readFileSync('test/keys/clent.pem'),
cert: fs.readFileSync('test/keys/clent.crt')
};
https.createServer(options, function (req,res) {
res.writeHead(200);
res.end("Hello Secure Word\n");
}).listen(8080);