詳解node如何讓一個端口同時支持https與http
眾所周知node是一個高性能的web服務(wù)器,使用它可以很簡單的創(chuàng)建一個http或https的服務(wù)器。
比如一個很簡單的http服務(wù)器:
var http = require('http');
var https = require('https');
var httpPort = 3345;
var server = http.createServer(function(req, res){
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('hello world!');
}).listen(httpPort);
https服務(wù)器需要生成證書,詳情請看這篇文章:HTTPS 的原理和 NodeJS 的實現(xiàn)。這里我們直接看最終成果,附件證書。
var https = require('https');
var fs = require('fs');
var httpsPort = 3346;
var options = {
key: fs.readFileSync('./cakey.pem'),
cert: fs.readFileSync('./cacert.pem')
};
var sserver = https.createServer(options, function(req, res){
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('secured hello world');
}).listen(httpsPort);
從上文我們可以看出,node生成的每個服務(wù)器必須分配一個端口。那么如果我們在工作中遇到一個需求:讓同一個端口或地址既支持http協(xié)議又支持https協(xié)議,這時候我們該怎么辦,有的同學很可能想到用nginx做反向代理,這不失為一個解決方案,但這也同樣意味著增加了產(chǎn)品的復雜度,用戶并不想去折騰ngnix。
辦法是有的,原理就要搬出OSI的七層模型:

HTTP與HTTPS都屬于應(yīng)用層協(xié)議,所以只要我們在底層協(xié)議中進行反向代理,就可以解決這個問題! 剛好node可以讓我們很方便的創(chuàng)建一個tcp服務(wù)器!
所以我們的核心代碼如下:
var net = require('net');
var http = require('http');
var https = require('https');
var fs = require('fs');
var httpPort = 3345;
var httpsPort = 3346;
var server = http.createServer(function(req, res){
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('hello world!');
}).listen(httpPort);
var options = {
key: fs.readFileSync('./cakey.pem'),
cert: fs.readFileSync('./cacert.pem')
};
var sserver = https.createServer(options, function(req, res){
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('secured hello world');
}).listen(httpsPort);
net.createServer(function(socket){
socket.once('data', function(buf){
console.log(buf[0]);
// https數(shù)據(jù)流的第一位是十六進制“16”,轉(zhuǎn)換成十進制就是22
var address = buf[0] === 22 ? httpsPort : httpPort;
//創(chuàng)建一個指向https或http服務(wù)器的鏈接
var proxy = net.createConnection(address, function() {
proxy.write(buf);
//反向代理的過程,tcp接受的數(shù)據(jù)交給代理鏈接,代理鏈接服務(wù)器端返回數(shù)據(jù)交由socket返回給客戶端
socket.pipe(proxy).pipe(socket);
});
proxy.on('error', function(err) {
console.log(err);
});
});
socket.on('error', function(err) {
console.log(err);
});
}).listen(3344);
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Node.js連接postgreSQL并進行數(shù)據(jù)操作
自從MySQL被Oracle收購以后,PostgreSQL逐漸成為開源關(guān)系型數(shù)據(jù)庫的首選。這篇文章就給大家介紹了關(guān)于Node.js如何連接postgreSQL數(shù)據(jù)庫,并進行數(shù)據(jù)操作的方法,有需要的朋友們可以參考借鑒,下面來一起看看吧。2016-12-12
node.js中事件觸發(fā)器events的使用方法實例分析
這篇文章主要介紹了node.js中事件觸發(fā)器events的使用方法,結(jié)合實例形式分析了node.js事件觸發(fā)器events的功能、原理及基本使用方法,需要的朋友可以參考下2019-11-11
Node.js node-schedule定時任務(wù)隔多少分鐘執(zhí)行一次的方法
這篇文章主要介紹了Node.js node-schedule定時任務(wù)隔多少分鐘執(zhí)行一次的方法,本文給出了每隔 15 分鐘、 30 分鐘執(zhí)行一次任務(wù)的編碼實例,需要的朋友可以參考下2015-02-02

