NodeJS创建HTTPHTTPS服务器与客户端
Posted 前端社
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NodeJS创建HTTPHTTPS服务器与客户端相关的知识,希望对你有一定的参考价值。
方式一:回调方式
var server = http.createServer((request, response) => {
// 接受客户端请求时触发
...
});
server.listen(10000, 'localhost', 511, () => {
// 开始监听
...
});
方式二:事件监听方式
var server = http.createServer();// 接受客户端请求时触发server.on('request', (request, rsponse) => { ...});server.listen(10000, 'localhost', 511);// 开始监听server.on('listening', () => { ...});
-
server.listen(port, [host], [backlog], [callback])中的backlog参数为整数,指定位于等待队列中客户端连接的最大数量,一旦超过这个长度,HTTP服务器将开始拒绝来自新客户端的连接,默认值为511。 -
在HTTP请求服务器时,会发送两次请求。一次是用户发出请求,另一次是浏览器为页面在收藏夹中的显示图标(默认为favicon.ico)而自动发出的请求。
关闭服务器
server.close();
// 服务器关闭时会触发close事件
server.on('close', () => {...});
超时
server.setTimeout(60 * 1000, () => {
console.log('超时了');
});
// 或者通过事件形式
server.setTimeout(60 * 1000);
server.on('timeout', () => {...});
server.on('error', (e) => { if(e.code === 'EADDRINUSE') { // 端口被占用 }});
获取客户端请求信息
Get请求
server.on('request', (request, response) => {
if(request.url !== '/favicon.ico') {
/* Get请求 */
var params = url.parse(req.url, true).query;
// 或者
// var params = querystring.parse(url.parse(request.url).query);
// 根据参数做处理
// ...
// 结束请求
response.end();
}
});
Post请求
server.on('request', (request, response) => {
request.setEncoding('utf-8');
if(request.url !== '/favicon.ico') {
let result = '';
request.on('data', (data) => {
result += data;
});
request.on('end', () => {
var params = JSON.parse(postData);
console.log(`数据接收完毕:${result}`);
});
// 结束本次请求
response.end();
}
// 结束本次请求
response.end(JSON.stringify({status: 'success'}));
});
转换URL字符串与查询字符串
querystring.stringify(obj, [sep], [eq])
querystring.parse(str, [sep], [eq], [option])
{maxKeys: number}
指定转换后对象中的属性个数
let str = querystring.stringify({name: 'ligang', age: 27});
console.log(str); // name=ligang&age=27
let obj = querystring.parse(str);
console.log(obj); // { name: 'ligang', age: '27' }
url.parse(urlStr, [parseQueryString])
url.resolve(from, to);
// http://ligangblog.com/javascript/a?a=1url.resolve('http://ligangblog.com/javascript/', 'a?a=1'); // http://ligangblog.com/a?a=1url.resolve('http://ligangblog.com/javascript/', '/a?a=1');
var urlStr = 'http://ligangblog.com/javascript/?name=lg&uid=1#a/b/c';
console.log(url.parse(urlStr, true));
/*
Url {
protocol: 'http:',
slashes: true,
auth: null,
host: 'ligangblog.com',
port: null,
hostname: 'ligangblog.com',
hash: '#a/b/c',
search: '?name=lg&uid=1',
query: { name: 'lg', uid: '1' },
pathname: '/javascript/',
path: '/javascript/?name=lg&uid=1',
href: 'http://ligangblog.com/javascript/?name=lg&uid=1#a/b/c'
}
*/
发送服务器端响应流
response.writeHead(statusCode, [reasonPhrase], [headers]);
// 或者
response.setHeader(name, value);
response.writeHead(200, {'Content-Type': 'text/plain',
'Access-Control-Allow-Origin': 'http://localhost'});
// 或者
response.statusCode = 200;
response.setHeader('Content-Type', 'text/plain');
response.setHeader('Access-Control-Allow-Origin', 'http://localhost');
writeHead和setHeader区别:
/* 获取响应头中的某个字段值 */response.getHeader(name);/* 删除一个响应字段值 */response.removeHeader(name);/* 该属性表示响应头是否已发送 */response.headersSent;/* 在响应数据的尾部增加一个头信息 */response.addTrailers(headers);
// 必须再响应头中添加Trailer字段,并且其值设置为追加的响应头中所指定的字段名response.write(200, {'Content-Type': 'text/plain', 'Trailer': 'Content-MD5'});response.write('....');response.addTrailers({'Content-MD5', '...'});response.end();
/* 设置请求超时时间2分钟 */response.setTimeout(2 * 60 * 1000, () => { console.error('请求超时!'); });// 或者response.setTimout(2 * 60 * 1000);response.on('timeout', () => { console.error('请求超时!');});/* 连接中断 */response.on('close', () => { console.error('连接中断!');});
/**
* HTTP服务端
* Created by ligang on 17/5/28.
*/
import http from 'http';
var server = http.createServer();
// 接受客户端请求时触发
server.on('request', (request, response) => {
if(request.url !== '/favicon.ico') {
response.setTimeout(2 * 60 * 1000, () => {
console.error('请求超时!');
});
response.on('close', () => {
console.error('请求中断!');
});
let result = '';
request.on('data', (data) => {
result += data;
});
request.on('end', () => {
console.log(`服务器数据接收完毕:${result}`);
response.statusCode = 200;
response.write('收到!');
response.end(); // 结束本次请求
});
}
});
server.listen(10000, 'localhost', 511);
// 开始监听
server.on('listening', () => {
console.log('开始监听');
});
server.on('error', (e) => {
if(e.code === 'EADDRINUSE') {
console.log('端口被占用');
}else {
console.log(`发生错误:${e.code}`);
}
});
HTTP客户端
var req = http.request(options, callback);// get请求var req = http.get(options, callback);// 向目标网站发送数据req.write(chunk, [encoding]);// 结束本次请求req.end([chucnk], [encoding]);// 中止本次请求req.abort();
/**
* HTTP客户端
* Created by ligang on 17/5/30.
*/
import http from 'http';
const options = {
hostname: 'localhost',
port: 10000,
path: '/',
method: 'post'
},
req = http.request(options);
req.write('你好,服务器');
req.end();
req.on('response', (res) => {
console.log(`状态码:${res.statusCode}`);
let result = '';
res.on('data', (data) => {
result += data;
});
res.on('end', () => {
console.log(`客户端接受到响应:${result}`);
})
});
req.setTimeout(60* 1000, () => {
console.log('超时了');
req.abort();
});
req.on('error', (error) => {
if(error.code === 'ECONNERSET') {
console.log('socket端口超时');
}else {
console.log(`发送错误:${error.code}`);
}
});
代理服务器
/**
* HTTP代理
* Created by ligang on 17/5/30.
*/
import http from 'http';
import url from 'url';
/**
* 服务端
*/
const server = http.createServer(async (req, res) => {
// req.setEncoding('utf-8');
/* 超时 2分钟 */
res.setTimeout(2 * 60 * 1000, () => {
// ...
});
/* 连接中断 */
res.on('close', () => {
// ...
});
let options = {},
result = "";
options = await new Promise((resolve, reject) => {
if(req.method === 'GET') {
options = url.parse('http://localhost:10000' + req.url);
resolve(options);
}else if(req.method === 'POST') {
req.on('data', (data) => {
result += data;
});
req.on('end', () => {
options = url.parse('http://localhost:10000' + req.url);
// post请求必须制定
options.headers = {
'content-type': 'application/json',
};
resolve(options);
});
}
});
options.method = req.method;
let content = await clientHttp(options, result ? JSON.parse(result) : result);
res.setHeader('Content-Type', 'text/html');
res.write('<html><head><meta charset="UTF-8" /></head>')
res.write(content);
res.write('</html>');
// 结束本次请求
res.end();
});
server.listen(10010, 'localhost', 511);
/* 开始监听 */
server.on('listening', () => {
// ...
});
/* 监听错误 */
server.on('error', (e) => {
console.log(e.code);
// ...
});
/**
* 客户端
* @param options 请求参数
* @param data 请求数据
*/
async function clientHttp(options, data) {
let output = new Promise((resolve, reject) => {
let req = http.request(options, (res) => {
let result = '';
res.setEncoding('utf8');
res.on('data', function (chunk) {
result += chunk;
});
res.on('end', function () {
resolve(result);
});
});
req.setTimeout(60000, () => {
console.error(`连接后台超时 ${options.href}`);
reject();
req.abort();
});
req.on('error', err => {
console.error(`连接后台报错 ${err}`);
if (err.code === 'ECONNRESET') {
console.error(`socket超时 ${options.href}`);
} else {
console.error(`连接后台报错 ${err}`);
}
reject();
req.abort();
});
// 存在请求数据,发送请求数据
if (data) {
req.write(JSON.stringify(data));
}
req.end();
});
return await output;
}
HTTPS服务器
-
HTTPS使用https协议,默认端口号44; -
HTTPS需要向证书授证中心申请证书; -
HTTPS服务器与客户端之间传输是经过SSL安全加密后的密文数据;
创建公钥、私钥及证书
openssl genrsa -out privatekey.pem 1024
openssl req -new -key privatekey.pem -out certrequest.csr
openssl x509 -req -in certrequest.csr -signkey privatekey.pem -out certificate.pem
openssl pkcs12 -export -in certificate.pem -inkey privatekey.pem -out certificate.pfx
HTTPS服务
import https from 'https';
import fs from 'fs';
var pk = fs.readFileSync('privatekey.pem'),
pc = fs.readFileSync('certificate.pem');
var opts = {
key: pk,
cert: pc
};
var server = https.createServer(opts);
const options = {
hostname: 'localhost',
port: 1443,
path: '/',
method: 'post',
key: fs.readFileSync('privatekey.pem'),
cert: fs.readFileSync('certificate.pem'),
rejectUnhauthorized: false,
agent: false // 从连接池中指定挑选一个当前连接状态为关闭的https.Agent
},
req = https.request(options);
// 或者
const options = {
hostname: 'localhost',
port: 1443,
path: '/',
method: 'post',
key: fs.readFileSync('privatekey.pem'),
cert: fs.readFileSync('certificate.pem'),
rejectUnhauthorized: false,
};
// 显示指定https.Agent对象
options.agent = new https.Agent(options);
var req = https.request(options);
作者: 奋飛 来源 | https://blog.csdn.net/ligang2585116/article/details/72827781
设置星标,与10000+前端开发者共成长
以上是关于NodeJS创建HTTPHTTPS服务器与客户端的主要内容,如果未能解决你的问题,请参考以下文章