3 回答
TA贡献1789条经验 获得超8个赞
为了让 Firefox 中的测试更容易,我禁用了缓存。否则我将不得不手动清除缓存以获得准确的结果。不过,在使用 Chrome 时,我似乎没有遇到同样的问题。
请记住,我是 Go 新手,但这个问题让我发疯了......我遇到了与你完全相同的行为(显然)......
Go/http 似乎对模式的格式化方式很挑剔..
我搞砸了大约一个小时,终于能够使用以下代码获得一个工作示例:
// Working Code
package main
import "net/http"
func main() {
root := http.NewServeMux()
api := http.NewServeMux()
api.HandleFunc("/ping", myHandlerFunc)
root.Handle("/api/", http.StripPrefix("/api", api))
http.ListenAndServe(":8080", root)
}
func myHandlerFunc(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("pong\n"))
}
我尝试了尽可能多的不同配置(/就正斜杠而言),上面的代码是我让它工作的唯一方法..
具体指:
// Leading forward slash on /ping
api.HandleFunc("/ping", myHandlerFunc)
// The first /api/ is surrounded in forward slashes,
// the second /api only contains a leading forward slash
root.Handle("/api/", http.StripPrefix("/api", api))
将代码更改为此会导致 404...
// DOES NOT WORK!!
package main
import "net/http"
func main() {
root := http.NewServeMux()
api := http.NewServeMux()
api.HandleFunc("/ping", myHandlerFunc)
root.Handle("/api", http.StripPrefix("/api", api))
http.ListenAndServe(":8080", root)
}
func myHandlerFunc(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("pong\n"))
}
我希望这在某种程度上有所帮助!干杯
TA贡献1871条经验 获得超13个赞
前几天我正在处理这个问题。我认为ServeMux期望有根树(以 开头/),或者它将路径解释为主机名。
模式名称固定,有根路径,如“/favicon.ico”,或有根子树,如“/images/”.... 模式可以选择以主机名开头,将匹配限制为仅该主机上的 URL。
我推测这ping被解释为主机名,这会导致 servermux 的运行方式变得怪异。
在人们编写的其他解决方案中,他们围绕 的位置进行更改,/以使ping路线最终为/ping。
就个人而言,我不喜欢我必须/api/在一个地方和/api另一个地方写作。在我的特殊情况下,我决定使用类似的东西:
root.Handle(createAPIEndpoints("/api/"))
...
func createAPIEndpoints(base string) (string, *http.ServeMux) {
mux := http.NewServeMux()
mux.HandleFunc(base+"ping", func(...){...})
mux.HandleFunc(base+"another", func(...){...})
// another buried servemux
mux.Handle(createMoreEndpoints(base+"more/"))
return base, mux
}
但是,如果您想用处理程序包装处理程序(例如使用StripPrefix或其他类型的中间件,由于返回 2 个值,这不能很好地工作。
TA贡献1871条经验 获得超8个赞
我遇到了类似的问题,但仅在您尝试/在嵌套路由器下定义根路径的情况下。
为了处理它,我重写了我自己的 stripPefix() 方法,如下所示:
package main
import "net/http"
func main() {
root := http.NewServeMux()
api := http.NewServeMux()
api.HandleFunc("/", myHandlerFunc)
root.Handle("/api", stripPrefix("/api", api))
http.ListenAndServe(":8080", root)
}
func myHandlerFunc(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("OK\n"))
}
// Modified version of http.StripPrefix()
func stripPrefix(prefix string, h http.Handler) http.Handler {
if prefix == "" {
return h
}
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if p := strings.TrimPrefix(r.URL.Path, prefix); len(p) < len(r.URL.Path) {
r2 := new(http.Request)
*r2 = *r
r2.URL = new(url.URL)
*r2.URL = *r.URL
if len(p) == 0 {
r2.URL.Path = "/"
} else {
r2.URL.Path = p
}
h.ServeHTTP(w, r2)
} else {
http.NotFound(w, r)
}
})
}
- 3 回答
- 0 关注
- 218 浏览
添加回答
举报