我有一個基本的中間件,它是一個 Logger 函數,當我body, err := ioutil.ReadAll(r.Body)在接下來的每個函數中執行時,http.Request 將為空。但我希望身體包含信息。我能做些什么?開始:r.HandleFunc("/login", server.Loger(server.GetTokenHandler()).ServeHTTP).Methods("POST")所以它是中間件:func (server Server) Loger(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { body, _ := ioutil.ReadAll(r.Body) server.Log.Info(r.URL, " Methods: ", r.Method, string(body)) h.ServeHTTP(w, r) //Calls handler h })}現在 r.Body 將為空:func (server Server) GetTokenHandler() http.Handler{ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { body, err := ioutil.ReadAll(r.Body) if err != nil{ http.Error(w, "", 400) server.Log.Error(err) return } fmt.Print(string(body)) })}
1 回答

DIEA
TA貢獻1820條經驗 獲得超2個贊
只能r.Body讀取一次。沒有其他辦法了。
如果多個中間件需要訪問數據,則需要將其保存為字節片并將其傳遞給后續中間件。
如果處理程序有上下文,您可以將正文數據作為上下文中的值傳遞。
另一種解決方案是 hack,是將數據存儲在 ReponseWriter 的標頭字段中。您不應忘記在返回時將其刪除,以免將其發送出去。隨后的中間件可以訪問標頭中的數據。
func (server Server) ReadBody(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
body, _ := ioutil.ReadAll(r.Body)
w.Header().Add("body", string(body))
h.ServeHTTP(w, r) //Calls handler h
w.Header().Del("body")
})
}
后續中間件將通過指令獲取主體數據data := w.Header().Get("body")。請注意,標頭值是字符串,而不是字節切片。
- 1 回答
- 0 關注
- 124 瀏覽
添加回答
舉報
0/150
提交
取消