我有以下Go代码:
package main
import (
"encoding/json"
"fmt"
"github.com/gorilla/mux"
"github.com/gorilla/handlers"
"log"
"net/http"
"io/ioutil"
)
type rLog struct {
Method string
URI string
FormParam string
}
func commonMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Content-Type", "application/json")
formBs, err := ioutil.ReadAll(r.Body)
if err != nil {
log.Fatalf("Failed to decode postFormByteSlice: %v", err)
}
rl := rLog{Method: r.Method, URI: r.RequestURI, FormParam: string(formBs)}
log.Printf("%+v", rl)
next.ServeHTTP(w, r)
})
}
func main() {
port := ":3000"
var router = mux.NewRouter()
router.Use(commonMiddleware)
router.HandleFunc("/m/{msg}", handleMessage).Methods("GET")
router.HandleFunc("/n/", handleNumber).Methods("POST")
headersOk := handlers.AllowedHeaders([]string{"Authorization"})
originsOk := handlers.AllowedOrigins([]string{"*"})
methodsOk := handlers.AllowedMethods([]string{"GET", "POST", "OPTIONS"})
fmt.Printf("Server is running at http://localhost%s\n", port)
log.Fatal(http.ListenAndServe(port, handlers.CORS(originsOk, headersOk, methodsOk)(router)))
}
func handleMessage(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
message := vars["msg"]
response := map[string]string{"message": message}
json.NewEncoder(w).Encode(response)
}
func handleNumber(w http.ResponseWriter, r *http.Request) {
log.Println(r.FormValue("name")) // this returns nothing
response := map[string]string{"name": "1"} // dummy response
json.NewEncoder(w).Encode(response)
}
我在这里尝试做的很简单。
commonMiddleware
内部完成)handleNumber
内部的表单数据,即name
(以及以后的更多内容),并对其进行逻辑处理。我现在遇到的问题是log.Println(r.FormValue("name"))
什么也没有返回,我真的很奇怪为什么会发生这种情况。
我尝试在r.ParseForm()
之前添加log.Println(r.FormValue("name"))
。但这没用。
然后,当我添加log.Println(r.Form)
行时,它将返回map[]
。
我在这里错过了什么?
答案 0 :(得分:4)
您试图两次阅读r.Body
,首先是在commonMiddleware
中使用ioutil.ReadAll(r.Body)
,然后在handleNumber
中使用r.ParseForm()
。你不能它是io.Reader
,您不能阅读两次。您可以改为使用例如r.ParseForm()
的中间装,然后使用已解析的表单数据。在中间件r.PosrForm.Encode()
中进行记录,在处理程序r.FormValue()
或r.Form.Get()
中进行提取。我认为应该这样做
func commonMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Content-Type", "application/json")
err:=r.ParseForm() //parse in middleware, data will be contained in r.PostForm
if err != nil {
log.Fatalf("Failed to decode postFormByteSlice: %v", err)
}
rl := rLog{Method: r.Method, URI: r.RequestURI, FormParam: r.PostForm.Encode()} //url.Values.Encode() stringifys form data
log.Printf("%+v", rl)
next.ServeHTTP(w, r)
})
}
func main() {
port := ":3000"
var router = mux.NewRouter()
router.Use(commonMiddleware)
router.HandleFunc("/m/{msg}", handleMessage).Methods("GET")
router.HandleFunc("/n/", handleNumber).Methods("POST")
}
func handleNumber(w http.ResponseWriter, r *http.Request) {
log.Println(r.PostForm.Get("name")) // or just r.Form.Get("name") or r.FormValue("name")
response := map[string]string{"name": "1"} // dummy response
json.NewEncoder(w).Encode(response)
}