Node.js+Express多域名/子域名路由配置不生效问题咨询
问题根因
你的写法存在两个核心错误:
- 时序逻辑错误:Express的路由匹配是在请求进入处理流程时就按已注册的路由顺序匹配完成的,你在
app.get('/')的请求处理函数内部才执行app.use('/', test)注册路由,这次请求已经匹配到了外层的app.get('/')逻辑,不会再触发刚注册的test路由。 - 无响应处理:在domain1的判断分支里,你注册完路由后没有给当前请求返回响应,也没有调用
next()传递请求,导致第一次访问domain1时请求会直接挂起,自然看不到返回结果,也不会报错。
多次请求后还会出现重复注册路由的冗余问题。
排查步骤
- 先在
if(host === "domain1.com:5000")分支里加console.log('匹配到domain1'),确认host判断逻辑是否生效,先排除host匹配错误的问题 - 观察访问domain1时的请求状态,如果请求长时间处于pending/超时状态,就对应无响应处理的问题
- 检查本地hosts文件是否已经配置了
domain1.com、domain2.com指向127.0.0.1,避免是域名解析问题导致走了else分支
正确实现方案
不要在请求处理函数内部动态注册路由,改为提前注册路由,在请求中间件里判断host后分发处理:
const express = require('express') const app = express() const testRouter = require('./routes/test.js') // 提前引入路由,不要放在请求处理里 app.set('view engine', 'ejs') // 所有请求先走中间件判断host app.use((req, res, next) => { const host = req.get('host') req.isDomain1 = host === 'domain1.com:5000' req.isDomain2 = host === 'domain2.com:5000' next() }) // 匹配domain1的请求走test路由 app.use('/', (req, res, next) => { if (req.isDomain1) { testRouter(req, res, next) } else { next() } }) // 处理domain2和其他域名的根路径请求 app.get('/', (req, res) => { if (req.isDomain2) { return res.send("Domain2") } res.send(req.get('host')) }) app.listen(5000)
如果多域名路由逻辑比较复杂,也可以直接用vhost中间件做域名分发,不需要自己手写host判断逻辑:
// 先安装依赖:npm i vhost const vhost = require('vhost') const express = require('express') const app = express() const domain1App = express() domain1App.use(require('./routes/test.js')) const domain2App = express() domain2App.get('/', (req, res) => res.send('Domain2')) app.use(vhost('domain1.com', domain1App)) app.use(vhost('domain2.com', domain2App)) app.listen(5000)
内容的提问来源于stack exchange,提问作者KindCoder
相关产品推荐
相关产品推荐

