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

Go使用gorilla/mux时http.HandleFunc注册路由未触发如何解决

你的代码存在两个核心问题,直接导致路由handler不执行:

1. 路由注册对象不匹配

你在循环中使用http.HandleFunc()注册的路由,是绑定到Go标准库默认的全局路由实例上的,但你启动服务时http.ListenAndServe()的第二个参数传入的是自己新建的mux.Router实例,相当于所有注册的页面路由完全没有生效,所有请求只会走你给router配置的静态文件兜底逻辑,所以才会返回静态资源的目录列表。

2. 循环闭包变量捕获错误

就算把路由注册到正确的mux.Router实例上,你当前的handler写法也会出现逻辑错误:for循环里的page变量是同一块内存地址,每次迭代只是更新该地址存储的值,直接在闭包里引用page的话,所有handler最终捕获到的都会是循环结束时最后一个page的值,无法对应每个路径预期的page数据。

修正后的代码

func main() {
defer func() {
    if r := recover(); r != nil {
        fmt.Printf("Recovering from panic, error is: %v \n", r)
    }
}()
    router := mux.NewRouter()
    router.Use(middlewareHeaders)

    // 提前解析模板,保证handler执行时能拿到正确的模板实例
    var err error
    tmpl, err = template.ParseGlob("views/*")
    if err != nil {
        panic(err.Error())
    }

    for _, page := range pages.Pages {
        fmt.Print("page: ")
        fmt.Println(page.Slug)
        // 定义局部变量捕获当前迭代的page,解决闭包变量共享问题
        currentPage := page
        // 将路由注册到实际使用的mux.Router实例上
        router.HandleFunc(currentPage.Slug, func(w http.ResponseWriter, r *http.Request) {
            fmt.Println("http.HandleFunc")
            err := tmpl.ExecuteTemplate(w, currentPage.Template, currentPage)
            if err != nil {
                http.Error(w, err.Error(), http.StatusInternalServerError)
            }
        })
    }

    router.PathPrefix("/").HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
        http.FileServer(http.Dir("./static/")).ServeHTTP(res, req)
    })

    fmt.Println("Server running on localhost" + pages.Config.Port)

    err = http.ListenAndServe(pages.Config.Port, handlers.CompressHandler(router))
    if err != nil {
        log.Fatal(err)
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 13:36:03