在Go的http包中,如何获取POST请求的查询字符串?


113

我正在使用httpGo中的程序包来处理POST请求。如何访问和解析Request对象中查询字符串的内容?我从官方文档中找不到答案。


要记住的一件事是,如果您使用cURL发送请求并且r.FormValue("id")用于获取查询参数,则无法通过cURL中的表单数据发送i(即,curl 0.0.0.0:8888 -d id=foobar将不起作用)。您必须通过查询参数(curl 0.0.0.0:8888?id=foobar)发送它。

Answers:


144

根据定义,QueryString 位于URL中。您可以使用req.URLdoc)访问请求的URL 。URL对象具有一个返回类型的Query()方法(doc),该Values类型只是map[string][]stringQueryString参数的一个。

如果您要查找的是HTML表单提交的POST数据,那么(通常)这是请求正文中的键/值对。您的回答是正确的,您可以调用该字段ParseForm(),然后使用req.Formfield获取键-值对的映射,但是您也可以调用FormValue(key)以获取特定键的值。这ParseForm()在需要时调用,并获取值,而不管它们如何发送(即,在查询字符串中还是在请求正文中)。


2
感谢您的精确度。
法比恩

2
我发现'req.FormValue(key)'方法更快,可以为您完成解析url所需的所有代码。
OnlyAngel 2014年

6
req.URL.RawQuery?如果有帮助,则返回GET请求后的所有内容。
kouton 2014年

我发现有趣的是req.Form是空数组,除非req.formValue(“ some_field”)在租约中被调用一次。
钱陈

万分感谢!@kouton
Aditya Varma

127

这是有关如何访问GET参数的更具体的示例。该Request对象有一个为您解析它们的方法,称为Query

假设请求网址为http:// host:port / something?param1 = b

func newHandler(w http.ResponseWriter, r *http.Request) {
  fmt.Println("GET params were:", r.URL.Query())

  // if only one expected
  param1 := r.URL.Query().Get("param1")
  if param1 != "" {
    // ... process it, will be the first (only) if multiple were given
    // note: if they pass in like ?param1=&param2= param1 will also be "" :|
  }

  // if multiples possible, or to process empty values like param1 in
  // ?param1=&param2=something
  param1s := r.URL.Query()["param1"]
  if len(param1s) > 0 {
    // ... process them ... or you could just iterate over them without a check
    // this way you can also tell if they passed in the parameter as the empty string
    // it will be an element of the array that is the empty string
  }    
}

还要注意:“ Values映射中的键[即Query()返回值]区分大小写。”


4
一个以前的答案已经提到的,并链接到正是这样做的文档(和它没有将与一个出界的恐慌为例切片参考如果所需字段不存在,使用r.URL.Query().Get("moviename"),以避免这个致命的错误)。
Dave C

1
谢谢(你的)信息。是的,这些文档对我来说有点令人困惑,因此我将其发布为更多的“实例”,以防万一。修复了nil检查。使用Get方法仅在存在多个时才返回第一个,因此这是更多示例。有用的信息,谢谢!
rogerdpack 2015年

另外,我不认为您可以将字符串与nil进行比较:devs.cloudimmunity.com/gotchas-and-common-mistakes-in-go-golang即字符串!=“”有效
James Milner

我不认为代码可以编译,示例是否完整。您无法比较以Values.Get()返回的空字符串nilgolang.org/pkg/net/url/#Values
Daniel Farrell '18

19

下面是一个示例:

value := r.FormValue("field")

有关更多信息。关于http软件包,您可以在此处访问其文档。 FormValue基本上按该顺序返回它找到的第一个POST或PUT值或GET值。


8

这是一个简单的示例:

package main

import (
    "io"
    "net/http"
)
func queryParamDisplayHandler(res http.ResponseWriter, req *http.Request) {
    io.WriteString(res, "name: "+req.FormValue("name"))
    io.WriteString(res, "\nphone: "+req.FormValue("phone"))
}

func main() {
    http.HandleFunc("/example", func(res http.ResponseWriter, req *http.Request) {
        queryParamDisplayHandler(res, req)
    })
    println("Enter this in your browser:  http://localhost:8080/example?name=jenny&phone=867-5309")
    http.ListenAndServe(":8080", nil)
}

在此处输入图片说明



5

以下文字来自官方文件。

表单包含已解析的表单数据,包括URL字段的查询参数POST或PUT表单数据。该字段仅在调用ParseForm之后可用。

因此,下面的示例代码将起作用。

func parseRequest(req *http.Request) error {
    var err error

    if err = req.ParseForm(); err != nil {
        log.Error("Error parsing form: %s", err)
        return err
    }

    _ = req.Form.Get("xxx")

    return nil
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.