beego不支持子域名路由,因其路由仅匹配request.url.path,忽略host头;子域名分发必须由nginx等反向代理前置完成,框架内只能通过路径前缀或手动host校验实现逻辑隔离。

Beego 本身不支持子域名或泛域名的原生路由匹配,所有域名层的分发必须由反向代理(如 Nginx)前置完成,框架只处理路径级路由。
为什么 beego.Router 无法匹配子域名
beego.Router 的第一个参数是路径(path),不是完整 URL;它只解析 Request.URL.Path,完全忽略 Host 头。即使你写 beego.Router("admin.example.com/", &controllers.AdminController{}),这个字符串会被当作普通路径字面量处理,不会触发子域名识别。
常见错误现象:beego.Router("api.example.com/v1/users", ...) 注册后,访问 http://api.example.com/v1/users 仍 404 —— 因为 beego 实际收到的 Path 是 /v1/users,而你注册的路径字面量根本不存在。
- beego 启动时监听的是
0.0.0.0:8080这类地址,不绑定任何域名 - HTTP/1.1 协议中,
Host是请求头字段,不是 URL 路径的一部分 - 框架所有路由匹配逻辑都基于
ctx.Request.URL.Path,没有读取或校验ctx.Request.Host
Nginx 前置分流 + beego 路径路由是最简可行方案
真实生产环境中,子域名必须靠反向代理做第一层分发。例如将 admin.example.com 和 api.example.com 分别代理到不同 beego 实例或同一实例的不同路径前缀:
server {
listen 80;
server_name admin.example.com;
location / {
proxy_pass http://127.0.0.1:8081/;
proxy_set_header Host $host;
}
}
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://127.0.0.1:8082/;
proxy_set_header Host $host;
}
}
或者统一代理到同一个 beego 进程,但用路径前缀区分逻辑域:
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
admin.example.com → /admin/* → beego.Router("/admin/:action", &AdminController{})api.example.com → /api/* → beego.Router("/api/:version/:resource", &APIController{})
注意:此时 beego 内部无需感知域名,只需按路径规则注册即可,也避免了在代码里硬编码域名带来的部署耦合。
如果坚持在 beego 内部做 Host 判断,只能手动拦截
你可以在全局 Filter 或每个 Controller 的 Prepare() 方法里读取 ctx.Request.Host,然后手动跳转或返回错误。但这不属于路由系统能力,而是业务逻辑兜底:
func (c *BaseController) Prepare() {
host := c.Ctx.Request.Host
if strings.HasPrefix(host, "admin.") {
// 允许继续
} else if strings.HasPrefix(host, "api.") {
// 允许继续
} else {
c.Ctx.Output.SetStatus(400)
c.Data["json"] = map[string]string{"error": "invalid host"}
c.ServeJSON()
return
}
}
容易踩的坑:
- Filter 中不能调用
c.Redirect()后继续执行,需加return显式中断 - HTTPS 场景下,Nginx 若未透传
X-Forwarded-Host,ctx.Request.Host可能是127.0.0.1:8080,需配合proxy_set_header Host $host - 这种判断放在每个 Controller 里重复写,违背 DRY;应抽到基类或中间件,但 beego 中间件(FilterFunc)不自动继承,仍需显式注册
真正需要多域名支撑的项目,往往已超出 beego 的设计边界——它定位是 MVC Web 框架,不是边缘网关。把域名、SSL、负载均衡这些事交给 Nginx 或 Cloudflare,让 beego 专注处理好 /user/:id 这类路径逻辑,才是稳定且可维护的做法。










