【问题标题】:Gin Gonic array of values from PostForm来自 PostForm 的 Gin Gonic 值数组
【发布时间】:2017-02-20 10:15:40
【问题描述】:

我正在尝试使用 Go / Gin Gonic 从 HTML 表单中捕获 Post 值的数组——在 PHP 中我会使用类似的东西:

<form method="POST" enctype="multipart/form-data" action="mygo">
 <input type=hidden name="emails[]" value="email1@email.com">
 <input type=hidden name="emails[]" value="email2@email.com">
 <input type=hidden name="emails[]" value="email3@email.com">
</form>

但是,这似乎不适用于 Gin Gonic(或 Go )。

我也试过了:

<form method="POST" enctype="multipart/form-data" action="mygo">
 <input type=hidden name="emails" value="email1@email.com">
 <input type=hidden name="emails" value="email2@email.com">
 <input type=hidden name="emails" value="email3@email.com">
</form>

与其他地方一样,建议这样做会导致c.PostForm("emails") 返回一个切片。但是在实践中,这似乎反而将最后一个值作为字符串返回:(

有趣的是,c.Request.PostForm 返回一个空映射,即使首先调用了 c.Request.ParseForm()。我做错了什么?

去表格:

func main() {
// ...
    router.POST("mygo",parseFunc)
}

func mygo(c *gin.Context) {
  c.Request.ParseForm()
  log.Printf("%v",c.Request.PostForm["emails"]) // ""
  log.Printf("%v",c.PostForm("emails") // "email3@email.com"
}

【问题讨论】:

  • 要获取多个值,您需要直接使用Request.FormRequest.PostForm 映射。如果这些不存在,请显示minimal reproducible example。例如,您显示的表单将通过 GET 提交到生成表单的相同 url。
  • @JimB - 编辑显示 MCV 示例 :)
  • 对不起,您将不得不创建一个更完整的示例,因为您所展示的内容应该仍然有效..
  • @JimB - 啊,我认为我的问题有两个。首先 c.Request.PostForm 可能根本不起作用,因为我的表单中没有显示示例enctype="multipart/form-data" .. 从技术上讲,我认为我不需要我的表单是多部分的,如果我这样做了,我认为只是意味着调用ParseMultipartForm 而不是ParseForm - 但是当我使用gonic 调用c.PostForm 时调用ParseMultipartForm,但似乎gonic 方法手动返回only the first value - 将检查并更新。
  • 预计只返回第一个值的方法,因为这就是标准库 http.Request 方法的工作原理。

标签: go go-gin


【解决方案1】:

为了使其正常工作,您有两种方法

<form method="POST" enctype="multipart/form-data" action="mygo">
 <input type=hidden name="emails" value="email1@email.com">
 <input type=hidden name="emails" value="email2@email.com">
 <input type=hidden name="emails" value="email3@email.com">
</form>

r.POST("/", func(c *gin.Context) {
        c.Request.ParseMultipartForm(1000)
        for key, value := range c.Request.PostForm {
            fmt.Println(key,value)
        }
    })

要么

    <form method="POST" action="mygo">
     <input type=hidden name="emails" value="email1@email.com">
     <input type=hidden name="emails" value="email2@email.com">
     <input type=hidden name="emails" value="email3@email.com">
    </form>

 r.POST("/", func(c *gin.Context) {
            c.Request.ParseForm()
            for key, value := range c.Request.PostForm {
                fmt.Println(key,value)
            }
        })

两者都给出相同的结果

emails [email1@email.com email2@email.com email3@email.com]

【讨论】:

    【解决方案2】:

    使用最新版本的 gin-gonic (v1.2),您可以:

    emails := c.PostFormArray("emails")
    

    那么emails 将是[]string

    Parseiterate 没有必要了。

    【讨论】:

      【解决方案3】:

      此代码的问题有两个。发布我的答案以防其他人遇到这些问题。

      1. c.Request.PostForm 在这种情况下返回空,因为表单是多部分的,ParseForm 只解析非多部分的表单。为了在此处获取数据,请将表单类型更改为非多部分或在访问帖子值之前调用 ParseMultipartForm
      2. c.PostForm() 只返回第一个值,因为这就是 Gin Gonic 中的包装器所做的。为了访问所有值,需要访问原始的c.Request.PostForm 数据,然后在正确解析之后。

      感谢@JimB 的协助。

      【讨论】:

        【解决方案4】:

        我知道它已经晚了大约 5 年,但由于我也在寻找这个,我认为如果我分享我的答案,它仍然对某人有用。

        最简单的方法之一是:

        在 HTML 中

        <form method="POST" enctype="multipart/form-data" action="mygo">
         <input type=hidden name="emails[]" value="email1@email.com">
         <input type=hidden name="emails[]" value="email2@email.com">
         <input type=hidden name="emails[]" value="email3@email.com">
        </form>

        在 GO 中:

        emails, ok := c.Request.PostForm["emails[]"]
        if ok {
            fmt.Println("this are your emails: ", emails)
        }

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-09-07
          • 1970-01-01
          • 1970-01-01
          • 2015-09-04
          • 2020-03-03
          • 2018-11-07
          • 2020-04-14
          • 1970-01-01
          相关资源
          最近更新 更多