前往:将用户名添加到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:

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)
}

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

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

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)
}

To use this then you would do something like this :

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)