goblog 學習二

0day發表於2021-03-21

今天學習了go module 和路由,引進社群的mux包。

路由

標準庫自帶http.ServeMux,但有三個問題:

  1. 不支援URL路徑引數
  2. 不支援請求方法的過濾,如果GET和POST
  3. 不支援路由的命名

教程選用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 協議》,轉載必須註明作者和本文連結

相關文章