如何使用vhost与Node.js基于数据库用户名动态创建子域名
Express 动态子域名实现方案
核心逻辑
无需提前为每个用户手动注册vhost,使用通配符匹配所有子域名,请求到来时实时校验子域名对应的用户名是否存在于数据库,即可实现动态适配所有合法用户的子域名需求。
实现步骤
- 依赖准备
确保已安装所需依赖:
npm install express vhost
你还需要准备自己的数据库查询/API调用逻辑,用来校验用户名合法性。
2. 完整代码实现
const express = require('express'); const vhost = require('vhost'); const app = express(); const domain = "localhost"; // 所有用户子域名共用的处理逻辑,可根据需求自定义 const userSubApp = express(); userSubApp.get('/', (req, res) => { res.send(`当前访问的是用户 ${req.username} 的专属子域名`); }); // 子域名合法性校验中间件 async function checkSubdomainValid(req, res, next) { // 提取子域名前缀(即用户名) const username = req.vhost[0]; try { // 此处替换为你的API调用/数据库查询逻辑,判断用户名是否存在 // 示例:const res = await fetch(`https://your-api.com/user/exists?username=${username}`); // 示例:const isUserExist = await res.json(); const isUserExist = true; // 测试用占位符,实际替换为真实查询结果 if (!isUserExist) { return res.status(404).send('该子域名不存在'); } // 挂载用户名到请求对象,后续逻辑可直接使用 req.username = username; next(); } catch (error) { return res.status(500).send('子域名校验出错'); } } // 注册通配符vhost,匹配所有*.localhost的请求 app.use(vhost(`*.${domain}`, checkSubdomainValid, userSubApp)); // 主站路由,不受子域名匹配影响 app.get('/', (req, res) => { res.send('主站页面'); }); app.listen(3000, () => { console.log('服务已启动,端口3000'); });
注意事项
- 本地测试需要修改系统hosts文件,将测试用子域名(如
user1.localhost)指向127.0.0.1;生产环境需要配置域名泛解析,将*.你的正式域名指向服务器IP。 - 该方案支持新增用户实时生效,无需重启服务更新配置。
- 若要优化性能,可添加Redis缓存已存在的用户名,降低数据库/API请求频率。
内容的提问来源于stack exchange,提问作者Tony George
相关产品推荐
相关产品推荐

