如何在一个https.createServer()中按条件运行两个不同的app.js?
在单个HTTP/HTTPS服务器中承载两个独立Node.js网站的方案
核心思路是通过解析请求头中的Host字段匹配域名,将请求转发给对应的应用或静态资源服务,实现一个服务器实例承载多个独立站点。以下分两种场景给出实现方案:
场景1:承载Express/Koa等框架的独立应用(app.js)
如果你的两个站点是基于Express、Koa这类Web框架开发的,直接在服务器回调中根据域名路由到对应框架实例即可:
const https = require('https'); const fs = require('fs'); const path = require('path'); // 引入两个独立的框架应用 const app1 = require('./folder1/app'); // 假设是Express/Koa实例 const app2 = require('./folder2/app'); // HTTPS证书配置(HTTP环境可直接替换为http.createServer,去掉此配置) const options = { key: fs.readFileSync(path.join(__dirname, './Cert/folder1.com.key'), 'utf8'), cert: fs.readFileSync(path.join(__dirname, './Cert/folder_com.crt'), 'utf8') }; // 创建HTTPS服务器 const server = https.createServer(options, (req, res) => { try { // 提取域名(去掉端口部分) const hostName = req.headers.host.split(':')[0]; // 根据域名路由到对应应用 switch(hostName) { case 'folder1.com': app1(req, res); // 直接让框架实例处理请求 break; case 'folder2.com': app2(req, res); break; default: // 处理未知域名的请求 res.writeHead(404, {'Content-Type': 'text/plain'}); res.end('未知域名'); } } catch (e) { console.error('请求处理错误:', e); res.writeHead(500, {'Content-Type': 'text/plain'}); res.end('服务器内部错误'); } }); // 启动服务器 const port = process.env.PORT || 443; server.listen(port, () => { console.log(`服务器已启动,监听端口: ${port}`); });
场景2:承载静态HTML站点
如果两个站点是纯静态HTML文件,可使用node-static库提供静态资源服务,优化后的实现代码如下:
const path = require("path"); const fs = require('fs'); const https = require('https'); const static = require('node-static'); const { Server: SocketIOServer } = require("socket.io"); // 初始化两个站点的静态资源服务 const folder1Static = new static.Server('./folder1'); const folder2Static = new static.Server('./folder2'); // HTTPS证书配置 const options = { key: fs.readFileSync(path.join(__dirname, './Cert/folder1.com.key'), 'utf8'), cert: fs.readFileSync(path.join(__dirname, './Cert/folder_com.crt'), 'utf8') }; // 创建服务器并处理请求路由 const server = https.createServer(options, (req, res) => { try { const hostName = req.headers.host.split(':')[0]; console.log(`处理请求: ${hostName}${req.url}`); switch(hostName) { case 'folder1.com': folder1Static.serve(req, res); break; case 'folder2.com': folder2Static.serve(req, res); break; default: res.writeHead(404, {'Content-Type': 'text/plain'}); res.end('未知域名'); } } catch(e) { console.error('静态服务错误:', e); res.writeHead(500, {'Content-Type': 'text/plain'}); res.end('服务器内部错误'); } }); // 可选:配置共享Socket.IO(如需独立实例可使用命名空间) const io = new SocketIOServer(server, {log: false}); // 启动服务器 const port = process.env.PORT || 443; server.listen(port, () => { console.log(`服务器已启动,监听端口: ${port}`); });
关键注意事项
- 证书适配:多域名场景建议使用通配符证书或SAN证书,避免重复配置;HTTP环境直接替换
https.createServer为http.createServer,删除证书配置即可。 - 域名解析:确保域名已正确解析到服务器IP,本地测试可修改
hosts文件添加映射(如127.0.0.1 folder1.com folder2.com)。 - 错误隔离:必须添加异常捕获逻辑,避免单个站点的错误导致整个服务器崩溃。
- Socket.IO隔离:如果两个站点需要独立的Socket.IO服务,可通过命名空间区分(如
io.of('/folder1')和io.of('/folder2'))。
内容的提问来源于stack exchange,提问作者Gautam Kumar
相关产品推荐
相关产品推荐

