今天學習了go module 和路由,引進社群的mux包。
路由
標準庫自帶http.ServeMux
,但有三個問題:
- 不支援URL路徑引數
- 不支援請求方法的過濾,如果GET和POST
- 不支援路由的命名
教程選用Gorilla/mux作為路由器。實現精準匹配。用mux.Methods()區分請求方法;用Name()命名路由;
router.HandleFunc("/articles/{id:[0-9]+}", articlesShowHandler).Methods("GET").Name("articles.show")
中介軟體
引進中介軟體,解決重複度很高的程式碼:
w.Header().Set("Content-Type", "text/html; charset=utf-8")
實現的方式是,增加一箇中介軟體的函式:
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=utf-8")
// 2. 繼續處理請求
h.ServeHTTP(w, r)
})
}
然後使用 Gorilla Mux 的 mux.Use() 方法,在main()中載入中介軟體:router.Use(forceHTMLMiddleware)
URL中的 “/” 問題
雖然mux可以用:
router := mux.NewRouter().StrictSlash(true)
解決ip:3000/about/
後面“/”問題(301跳轉),但是沒法ip:3000/
仍然會有錯誤。最後解決辦法是增加一個預先處理請求的函式,用strings函式去掉末尾的“/”:
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)
})
}
用if語句做個判斷。簡單有效。
本作品採用《CC 協議》,轉載必須註明作者和本文連結