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

Chi路由器配置Host头匹配路由时仅最后注册路由生效问题

问题根因

Chi 路由器对同HTTP方法、同路径的路由注册遵循后注册覆盖先注册的规则,你当前代码中为两条GET类型的根路径/分别绑定不同中间件的写法,本质是在路由树的同一个节点重复注册handler,最终只有最后注册的默认路由会保留,RouteHeaders的Host匹配逻辑根本没有执行机会。

修复方案

方案1:使用官方Host中间件做路由拆分(推荐)

直接用Chi内置的middleware.Host做Host维度的路由分流,逻辑更清晰,不会出现路由覆盖问题:

r := chi.NewRouter()
r.Use(middleware.Logger)

// 定义Host为example.com时的专属路由
exampleRouter := chi.NewRouter()
exampleRouter.Get("/", func(w http.ResponseWriter, r *http.Request) {
    log.Println("Host: example.com")
    echo(w, r)
})
// 挂载Host匹配规则,命中example.com的请求会转发到专属路由处理
r.Use(middleware.Host("example.com", exampleRouter))

// 注册默认根路由,Host不匹配上述规则时才会走到这里
r.Get("/", func(w http.ResponseWriter, r *http.Request) {
    echo(w, r)
})

srv := &http.Server{
    Handler:      r,
    Addr:         "127.0.0.1:8080",
    WriteTimeout: 15 * time.Second,
    ReadTimeout:  15 * time.Second,
}
log.Fatal(srv.ListenAndServe())

方案2:正确使用RouteHeaders中间件

如果要使用RouteHeaders实现匹配,不能注册两条同路径路由,需要把Host匹配分支和默认逻辑合并到同一条路由的中间件链中:

r := chi.NewRouter()
r.Use(middleware.Logger)

// 构建头匹配中间件,命中Host规则时直接执行对应handler,不命中则放行
headerMatchMiddleware := middleware.RouteHeaders().
    Route("Host", "example.com", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        log.Println("Host: example.com")
        echo(w, r)
    })).
    Handler

// 仅注册一条根路由,中间件匹配失败时走默认响应逻辑
r.With(headerMatchMiddleware).Get("/", func(w http.ResponseWriter, r *http.Request) {
    echo(w, r)
})

srv := &http.Server{
    Handler:      r,
    Addr:         "127.0.0.1:8080",
    WriteTimeout: 15 * time.Second,
    ReadTimeout:  15 * time.Second,
}
log.Fatal(srv.ListenAndServe())

内容的提问来源于stack exchange,提问作者user672009

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 11:03:15