You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在一个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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 08:50:36