Gorilla Mux 中斜杆的处理方式
thub.com/gorilla/mux 是一个很不错的第三方库,用来扩展路由功能。这个库,我已经使用了一段时间,我很喜欢它的简洁,直观。如果你以前没有用过这个库,我强烈建议你试一下。
package main
import (
"fmt"
"log"
"net/http"
"github.com/gorilla/mux"
)
func main() {
router := mux.NewRouter()
router.HandleFunc("/items", postHandler).Methods(http.MethodPost)
router.HandleFunc("/items", getHandler).Methods(http.MethodGet)
log.Print("server starting")
log.Fatal(http.ListenAndServe(":8888", router))
}
func postHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "method %s, url %s", r.Method, r.URL)
}
func getHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "method %s, url %s", r.Method, r.URL)
}
十分的简洁。在上面的代码中,我注册了两个路由:GET /items 和 POST /items 。当你用 post 的方式访问 /items,你将会看到如下信息
method POST, url /items
然而,当你用 post 的方式访问 /items/ (请注意 items 后面的斜杠),你会得到一个意想不到的结果:
404 page not found
请给我提供一些有用的建议
上面的结果为什么是 404,我认为是这样的: mux包将 /items 和 /itmes/ 看做两个不同的 url,对应两个不同的业务逻辑进行处理。因此,为了处理上面那种结尾是斜线的问题,你只能为这两个路径注册相同的处理程序。个人认为这是一种很不友好的解决方案。
router := mux.NewRouter().StrictSlash(true)
上面的这个行代码,允许用户将 /items/ 的请求重定向到 /items,但是这也是有问题的,因为 mux 包将 post 请求重定向到 get 请求。这里应该是一个 bug。这对 mux 包并不新鲜,不知道什么原因,mux 包的开发团队至今没有修复这个 bug 并且 github 上也关闭了这个问题。所以他们的解决方案是什么?
现在看起来,我能想到的唯一解决这个问题的方案就是:在路由请求之前,创建一个中间件,用来去掉请求 URL 最后的斜杠。
func removeTrailingSlash(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
r.URL.Path = strings.TrimSuffix(r.URL.Path, "/")
next.ServeHTTP(w, r)
})
}
接着把中间件注册到 http监听器中。
// log.Fatal(http.ListenAndServe(":8888", router))
log.Fatal(http.ListenAndServe(":8888", removeTrailingSlash(router)))
感谢 Nate 在他的博客中提到了此解决方案。
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
推荐文章: