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
相关产品推荐
相关产品推荐

