关于路由后缀带斜杠跳转404问题
路由能识别/
和/about
,但是无法识别/about/
,发生404错误,这不是我预想的结果,无论/about
还是/about/
都应该正常跳转页面
package main
import (
"fmt"
"net/http"
"strings"
"github.com/gorilla/mux"
)
func main() {
router := mux.NewRouter()
router.HandleFunc("/", homeHandler).Methods("GET").Name("home")
router.HandleFunc("/about", aboutHandler).Methods("GET").Name("about")
// 404
router.NotFoundHandler = http.HandlerFunc(notFoundHandler)
// 中间件
router.Use(forceHTMLMiddleware)
// 用以监听本地 3000 端口以提供服务
http.ListenAndServe(":3000", router)
}
func homeHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "<h1>this is home</h1>")
}
func aboutHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "<h1>this is about</h1>")
}
func notFoundHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "<h1>请求页面未找到</h1>")
}
func forceHTMLMiddleware(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// 1.设置标头
w.Header().Set("Content-Type", "text/html; charset=utf8")
// 2.继续处理请求
h.ServeHTTP(w, r)
})
}
方法一:StrictSlash 处理
原理:重定向
...
router := mux.NewRouter()
// 处理路由后带"/"会报404的错
// 原理:重定向
// 无法兼容post请求
router.StrictSlash(true)
...
此方法并没有兼容post请求,且是通过重定向发起两次请求,并非是一个好方案
方法二:TrimSuffix 移除末端的斜杠再处理请求
func removeTrailingSlash(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// 1.除首页以外,移除所有路由后面带斜杠
if r.URL.Path != "/" {
r.URL.Path = strings.TrimSuffix(r.URL.Path, "/")
}
// 2.请求传递
next.ServeHTTP(w, r)
})
}
func main() {
router := mux.NewRouter()
...
// 用以监听本地 3000 端口以提供服务
http.ListenAndServe(":3000", removeTrailingSlash(router))
}