Go: 将用户名添加到URL中

huangapple go评论103阅读模式
英文:

Go: add username to URL

问题

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

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

Go代码:

  1. func homeHandler(w http.ResponseWriter, r *http.Request) {
  2. randIndex := rand.Intn(len(cityLibrary))
  3. ImageDisplay()
  4. WeatherDisplay()
  5. dispdata := AllApiData{
  6. Images: imagesArray,
  7. Weather: &WeatherData{
  8. Temp: celsiusNum,
  9. City: cityLibrary[randIndex],
  10. RainShine: rainOrShine,
  11. },
  12. }
  13. // http.Redirect(w, "/"+cityLibrary[randIndex], http.StatusFound) --> 无限重定向循环
  14. renderTemplate(w, "home", dispdata)
  15. }
  16. func main() {
  17. http.HandleFunc("/", homeHandler)
  18. http.Handle("/layout/", http.StripPrefix("/layout/", http.FileServer(http.Dir("layout"))))
  19. http.ListenAndServe(":8000", nil)
  20. }

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

英文:

How do I add the username of the current user, or other variables, to the end of the URL path in Go?

I tried using a http.Redirect(w, "/home/"+user, http.StatusFound), but that would create an infinite redirect loop.

Go:

  1. func homeHandler(w http.ResponseWriter, r *http.Request) {
  2. randIndex = rand.Intn(len(cityLibrary))
  3. ImageDisplay()
  4. WeatherDisplay()
  5. dispdata = AllApiData{Images: imagesArray, Weather: &WeatherData{Temp: celsiusNum, City: cityLibrary[randIndex], RainShine: rainOrShine}}
  6. //http.Redirect(w, "/"+cityLibrary[randIndex], http.StatusFound) --> infinite redirect loop
  7. renderTemplate(w, "home", dispdata)
  8. }
  9. func main() {
  10. http.HandleFunc("/", homeHandler)
  11. http.Handle("/layout/", http.StripPrefix("/layout/", http.FileServer(http.Dir("layout"))))
  12. http.ListenAndServe(":8000", nil)
  13. }

In this code, I'm trying to append the value of "City" to the end of the root URL. Should I be using regexp?

答案1

得分: 3

似乎发生这种情况是因为你没有一个 /{city}/ 处理程序,而 / 处理程序正在匹配所有被重定向到城市的请求:

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

请注意,由于以斜杠结尾的模式命名了一个根子树,因此模式 "/ "匹配所有未被其他已注册模式匹配的路径,而不仅仅是路径为 "/ "的 URL。

你需要做的是放置城市 URL 处理程序,如果你需要处理正则表达式模式,请参考这个,或者你可以使用更强大的路由器,比如 gorilla 的 mux


只使用 Go 而不使用 gorilla?我知道如何在 Gorilla 中做到这一点,但我只是想知道在 Go 中如何实现。

你可以按照之前提到的答案中所述,创建自己的自定义处理程序:

  1. type route struct {
  2. pattern *regexp.Regexp
  3. handler http.Handler
  4. }
  5. type RegexpHandler struct {
  6. routes []*route
  7. }
  8. func (h *RegexpHandler) Handler(pattern *regexp.Regexp, handler http.Handler) {
  9. h.routes = append(h.routes, &route{pattern, handler})
  10. }
  11. func (h *RegexpHandler) HandleFunc(pattern *regexp.Regexp, handler func(http.ResponseWriter, *http.Request)) {
  12. h.routes = append(h.routes, &route{pattern, http.HandlerFunc(handler)})
  13. }
  14. func (h *RegexpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  15. for _, route := range h.routes {
  16. if route.pattern.MatchString(r.URL.Path) {
  17. route.handler.ServeHTTP(w, r)
  18. return
  19. }
  20. }
  21. // no pattern matched; send 404 response
  22. http.NotFound(w, r)
  23. }

然后你可以像这样使用它:

  1. import "regexp"
  2. ...
  3. rex := RegexpHandler{}
  4. rex.HandlerFunc(regexp.MustCompile("^/(\w+?)/?"), cityHandler) // cityHandler 是你的常规处理程序函数
  5. rex.HandlerFunc(regexp.MustCompile("^/"), homeHandler)
  6. http.Handle("/", &rex)
  7. http.ListenAndServe(":8000", nil)
英文:

It seems this is happening because you don't have a /{city}/ handler and the / handler is matching all the requests being redirected to cities :

> Patterns name fixed, rooted paths, like "/favicon.ico", or rooted subtrees, like "/images/" (note the trailing slash). Longer patterns take precedence over shorter ones, so that if there are handlers registered for both "/images/" and "/images/thumbnails/", the latter handler will be called for paths beginning "/images/thumbnails/" and the former will receive requests for any other paths in the "/images/" subtree.
>
> Note that since a pattern ending in a slash names a rooted subtree, the pattern "/" matches all paths not matched by other registered patterns, not just the URL with Path == "/".

What you need to do is put in the city url handler, if you need to handle RegEx patterns take a look at this or you could use a more powerful router like gorilla's mux.


> what just using Go without gorilla? I know how to do it in Gorilla but I'm just wondering how its done in Go.

You make your own custom handlers with as mentioned in the previously mentioned answer :
https://stackoverflow.com/a/6565407/220710

  1. type route struct {
  2. pattern *regexp.Regexp
  3. handler http.Handler
  4. }
  5. type RegexpHandler struct {
  6. routes []*route
  7. }
  8. func (h *RegexpHandler) Handler(pattern *regexp.Regexp, handler http.Handler) {
  9. h.routes = append(h.routes, &route{pattern, handler})
  10. }
  11. func (h *RegexpHandler) HandleFunc(pattern *regexp.Regexp, handler func(http.ResponseWriter, *http.Request)) {
  12. h.routes = append(h.routes, &route{pattern, http.HandlerFunc(handler)})
  13. }
  14. func (h *RegexpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  15. for _, route := range h.routes {
  16. if route.pattern.MatchString(r.URL.Path) {
  17. route.handler.ServeHTTP(w, r)
  18. return
  19. }
  20. }
  21. // no pattern matched; send 404 response
  22. http.NotFound(w, r)
  23. }

To use this then you would do something like this :

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

huangapple
  • 本文由 发表于 2014年8月30日 15:58:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/25580292.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定