英文:
Gorilla Mux router from inside handler only works once then gives 404 page not found
问题
我正在使用Gorilla mux
作为我的路由器,但是我遇到了一个非常奇怪的问题。在第一次请求服务器时,我得到了一个有效的响应。但是在后续的请求中,我收到了一个404页面未找到
的错误。控制台中没有错误信息。
我的代码非常简单(可以直接复制粘贴进行测试):
package main
import (
"fmt"
"github.com/gorilla/mux"
"log"
"net/http"
)
func main() {
router := mux.NewRouter()
router.HandleFunc("/", RootHandler).Name("root")
http.Handle("/", router)
log.Println("Listening on port 1337...")
if err := http.ListenAndServe(":1337", nil); err != nil {
log.Fatal("http.ListenAndServe: ", err)
}
}
func RootHandler(w http.ResponseWriter, r *http.Request) {
content := "Welcome to "
rootUrl, err := mux.CurrentRoute(r).Subrouter().Get("root").URL()
if err != nil {
log.Printf("mux.CurrentRoute(r).Subrouter().Get(\"root\").URL(): ", err)
}
response := content + rootUrl.String()
fmt.Fprintf(w, response)
}
经过一些代码注释和测试,似乎以下这行代码有问题:
rootUrl, err := mux.CurrentRoute(r).Subrouter().Get("root").URL()
在处理程序中使用当前请求获取路由器的方法来自于另一个StackOverflow帖子:https://stackoverflow.com/questions/23553061/how-to-call-a-route-by-its-name-from-inside-a-handler
但是由于某种奇怪的原因,它只能工作一次:
shell-1$ go run servertest.go
2014/10/30 13:31:34 Listening on port 1337...
shell-2$ curl http://127.0.0.1:1337
Welcome to /
shell-2$ curl http://127.0.0.1:1337
404 page not found
如你所见,控制台中没有错误信息。
有人知道为什么它只能工作一次吗?
英文:
I'm using Gorilla mux
as my router and I'm having a very strange behaviour. On the first request to the server, I get a valid response. But on subsequent requests, I receive a 404 page not found
. There are no errors in the console.
My code is pretty straightforward (it can be copy-pasted to test it right out):
package main
import (
"fmt"
"github.com/gorilla/mux"
"log"
"net/http"
)
func main() {
router := mux.NewRouter()
router.HandleFunc("/", RootHandler).Name("root")
http.Handle("/", router)
log.Println("Listening on port 1337...")
if err := http.ListenAndServe(":1337", nil); err != nil {
log.Fatal("http.ListenAndServe: ", err)
}
}
func RootHandler(w http.ResponseWriter, r *http.Request) {
content := "Welcome to "
rootUrl, err := mux.CurrentRoute(r).Subrouter().Get("root").URL()
if err != nil {
log.Printf("mux.CurrentRoute(r).Subrouter().Get(\"root\").URL(): ", err)
}
response := content + rootUrl.String()
fmt.Fprintf(w, response)
}
After some code commenting and tests, it seems the following line is the culprit:
rootUrl, err := mux.CurrentRoute(r).Subrouter().Get("root").URL()
This method of getting the router inside the handler using the current request comes from another StackOverflow post: https://stackoverflow.com/questions/23553061/how-to-call-a-route-by-its-name-from-inside-a-handler
But for a strange reason, it only works once:
shell-1$ go run servertest.go
2014/10/30 13:31:34 Listening on port 1337...
shell-2$ curl http://127.0.0.1:1337
Welcome to /
shell-2$ curl http://127.0.0.1:1337
404 page not found
As you can see, there are no errors in the console.
Does someone have an idea of why it only works once ?
答案1
得分: 2
问题是Subrouter()不是用来返回路由器的,而是用来创建一个路由器,因此它会改变调用它的路由器的匹配器,导致你丢失处理程序。
你可以尝试使用闭包将路由器传递给处理程序。
func RootHandler(router *mux.Router) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
...
}
}
英文:
The problem is Subrouter() isn't made to return the router, but to create one, thus it changes the matcher of the router it is called on, making you lose the handler.
You could try passing the router to the handler using closures instead.
func RootHandler(router *mux.Router) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
...
}
}
答案2
得分: 0
我遇到了这个问题,并通过重新初始化方法来解决它:
// 单独创建一个子路由器
subRoute := mux.CurrentRoute(req).Subrouter()
// 调用你想要的路由,并存储URL
url, err := subRoute.Get("check_authorization").URL("id", key, "password", token)
// 重新初始化方法为GET或者之前使用的任何方法
subRoute.Methods(http.MethodGet)
希望对你有帮助!
英文:
i run to this problem and fixe it by re initiating the methods
//create a subrouter separately \
subRoute := mux.CurrentRoute(req).Subrouter() \
//Call the Route u want and store the URL
url, err := subRoute.Get("check_authorization").URL("id", key, "password", token)
// re-initiate the method to GET or whatever u had before
subRoute.Methods(http.MethodGet)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论