英文:
Go: add username to URL
问题
如何将当前用户的用户名或其他变量添加到Go中URL路径的末尾?
我尝试使用http.Redirect(w, "/home/"+user, http.StatusFound)
,但这会创建一个无限重定向循环。
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) --> 无限重定向循环
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的末尾。我应该使用正则表达式吗?
英文:
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?
答案1
得分: 3
似乎发生这种情况是因为你没有一个 /{city}/
处理程序,而 /
处理程序正在匹配所有被重定向到城市的请求:
模式名称固定,根路径,如 "/favicon.ico",或根子树,如 "/images/"(注意末尾的斜杠)。较长的模式优先于较短的模式,因此如果同时为 "/images/" 和 "/images/thumbnails/" 注册了处理程序,则后者将被调用以处理以 "/images/thumbnails/" 开头的路径,而前者将接收任何其他路径在 "/images/" 子树中的请求。
请注意,由于以斜杠结尾的模式命名了一个根子树,因此模式 "/ "匹配所有未被其他已注册模式匹配的路径,而不仅仅是路径为 "/ "的 URL。
你需要做的是放置城市 URL 处理程序,如果你需要处理正则表达式模式,请参考这个,或者你可以使用更强大的路由器,比如 gorilla 的 mux
。
只使用 Go 而不使用 gorilla?我知道如何在 Gorilla 中做到这一点,但我只是想知道在 Go 中如何实现。
你可以按照之前提到的答案中所述,创建自己的自定义处理程序:
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 是你的常规处理程序函数
rex.HandlerFunc(regexp.MustCompile("^/"), homeHandler)
http.Handle("/", &rex)
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
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)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论