【问题标题】:http.Request r.FormValue returns nothing/map[]http.Request r.FormValue 不返回任何内容/map[]
【发布时间】:2018-12-29 19:42:20
【问题描述】:

我有以下 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)
}

我在这里尝试做的很简单。

  1. 我想记录所有 POST 表单数据(在 commonMiddleware 内完成)
  2. 访问handleNumber 中的表单数据,即name(以及更多稍后),并对其进行一些逻辑处理。

我现在遇到的问题是,log.Println(r.FormValue("name")) 什么也没返回,我真的很想知道为什么会这样。

我尝试在log.Println(r.FormValue("name")) 之前添加r.ParseForm()。但它没有用。

而且,当我添加log.Println(r.Form) 行时,它会返回map[]

我在这里错过了什么?

【问题讨论】:

  • 当控制进入您的commonMiddleware 函数时,您是否使用Go 调试器检查r 的内容?

标签: forms rest go middleware gorilla


【解决方案1】:

您确实阅读了两次r.Body,首先是在commonMiddlewareioutil.ReadAll(r.Body),然后在handleNumberr.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)
}

【讨论】:

  • 非常感谢您能以代码的形式展示给我看。
  • r.PostForm.Get()r.Form.Get() 如果您不调用 r.ParseMultipartForm()r.ParseForm() before'em,则在您的示例中将不起作用
猜你喜欢
  • 1970-01-01
  • 2018-10-24
  • 1970-01-01
  • 2021-10-02
  • 2020-04-27
  • 2019-04-06
  • 2012-02-15
  • 2020-09-07
  • 2021-11-22
相关资源
最近更新 更多