【问题标题】:Go: add username to URLGo:将用户名添加到 URL
【发布时间】:2014-11-08 15:50:17
【问题描述】:

如何将当前用户的用户名或其他变量添加到 Go 中 URL 路径的末尾?

我尝试使用 http.Redirect(w, "/home/"+user, http.StatusFound),但这会造成无限重定向循环。

去:

func homeHandler(w http.ResponseWriter, r *http.Request) {
    randIndex = rand.Intn(len(cityLibrary))
    ImageDisplay()
    WeatherDisplay()
    dispdata = AllApiData{Images: imagesArray, Weather: &WeatherData{Temp: celsiusNum, City: cityLibrary[randIndex], RainShine: rainOrShine}}

    //http.Redirect(w, "/"+cityLibrary[randIndex], http.StatusFound) --> infinite redirect loop

    renderTemplate(w, "home", dispdata)
    }

func main() {
    http.HandleFunc("/", homeHandler)

    http.Handle("/layout/", http.StripPrefix("/layout/", http.FileServer(http.Dir("layout"))))

    http.ListenAndServe(":8000", nil)
}

在这段代码中,我试图将“City”的值附加到根 URL 的末尾。我应该使用正则表达式吗?

【问题讨论】:

  • 代码的其余部分是什么样的?路由器和处理程序?
  • 添加了上面的代码。
  • /{city}/ url 的处理程序在哪里?
  • 我没有。我不知道如何使用正则表达式构造它。
  • 一秒钟我会写一个答案

标签: go


【解决方案1】:

这似乎是因为您没有/{city}/ 处理程序,而/ 处理程序正在匹配所有被重定向到城市的请求:

模式名称固定,有根路径,如“/favicon.ico”,或有根子树,如“/images/”(注意尾部斜杠)。较长的模式优先于较短的模式,因此如果同时为“/images/”和“/images/thumbnails/”注册了处理程序,则会为以“/images/thumbnails/”开头的路径调用后一个处理程序,而前者将接收对“/images/”子树中任何其他路径的请求。

请注意,由于以斜杠结尾的模式命名了根子树,因此模式“/”匹配其他注册模式不匹配的所有路径,而不仅仅是路径 ==“/”的 URL。

您需要做的是放入城市 url 处理程序,如果您需要处理 RegEx 模式,请查看 this 或者您可以使用更强大的路由器,例如 gorilla's mux


在没有 gorilla 的情况下使用 Go 怎么办?我知道如何在 Gorilla 中做到这一点,但我只是想知道它在 Go 中是如何做到的。

您可以使用前面提到的答案中提到的自定义处理程序: https://stackoverflow.com/a/6565407/220710

type route struct {
    pattern *regexp.Regexp
    handler http.Handler
}

type RegexpHandler struct {
    routes []*route
}

func (h *RegexpHandler) Handler(pattern *regexp.Regexp, handler http.Handler) {
    h.routes = append(h.routes, &route{pattern, handler})
}

func (h *RegexpHandler) HandleFunc(pattern *regexp.Regexp, handler func(http.ResponseWriter, *http.Request)) {
    h.routes = append(h.routes, &route{pattern, http.HandlerFunc(handler)})
}

func (h *RegexpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    for _, route := range h.routes {
        if route.pattern.MatchString(r.URL.Path) {
            route.handler.ServeHTTP(w, r)
            return
        }
    }
    // no pattern matched; send 404 response
    http.NotFound(w, r)
}

要使用它,你会做这样的事情:

import regexp

...

rex := RegexpHandler{}
rex.HandlerFunc(regexp.MustCompile("^/(\w+?)/?"), cityHandler) // cityHandler is your regular handler function
rex.HandlerFunc(regexp.MustCompile("^/"), homeHandler)
http.Handle("/", &rex)
http.ListenAndServe(":8000", nil)

【讨论】:

  • 谢谢。既然它是一个变量,我应该用什么代替 {city}?
  • @user3918985 如果您使用的是大猩猩的mux,您可以使用类似r.HandleFunc("/articles/{city}/", CityHandler) 的内容,请阅读此处的文档:gorillatoolkit.org/pkg/mux
  • 在没有 gorilla 的情况下使用 Go 怎么办?我知道如何在 Gorilla 中做到这一点,但我只是想知道它在 Go 中是如何做到的。
  • @user3918985 我添加了一个如何使用 RegEx 处理程序的示例,如果它是您想要的,请接受答案。
  • 注意,您也可以通过/req.URL.Path 拆分为CityHandler 来获取r.HandleFunc("/articles/{city}/", CityHandler) 中的城市。 {city} 将在 splits[1] 中。
猜你喜欢
  • 1970-01-01
  • 2014-08-17
  • 2020-03-31
  • 2018-12-18
  • 1970-01-01
  • 2018-06-15
  • 2016-04-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多