En el paquete http de Go, ¿cómo obtengo la cadena de consulta en una solicitud POST?


114

Estoy usando el httppaquete de Go para atender la solicitud POST. ¿Cómo puedo acceder y analizar el contenido de la cadena de consulta desde el Requestobjeto? No encuentro la respuesta en la documentación oficial.


Una cosa a tener en cuenta, si está usando cURL para enviar solicitudes y lo usa r.FormValue("id")para buscar un parámetro de consulta, no puede enviar i a través de los datos del formulario en cURL (es decir, curl 0.0.0.0:8888 -d id=foobarno funcionará). Debe enviarlo a través de los parámetros de consulta ( curl 0.0.0.0:8888?id=foobar).

Respuestas:


145

Un QueryString está, por definición , en la URL. Puede acceder a la URL de la solicitud utilizando req.URL( doc ). El objeto URL tiene un Query()método ( doc ) que devuelve un Valuestipo, que es simplemente uno map[string][]stringde los parámetros de QueryString.

Si lo que está buscando son los datos POST enviados por un formulario HTML , entonces este es (generalmente) un par clave-valor en el cuerpo de la solicitud. Tiene razón en su respuesta que puede llamar ParseForm()y luego usar el req.Formcampo para obtener el mapa de pares clave-valor, pero también puede llamar FormValue(key)para obtener el valor de una clave específica. Esto llama ParseForm()si es necesario y obtiene valores independientemente de cómo se enviaron (es decir, en la cadena de consulta o en el cuerpo de la solicitud).


2
Gracias por las precisiones.
Fabien

2
Encuentro el método 'req.FormValue (key)' más rápido y hago por usted todo el código necesario para analizar previamente la url.
OnlyAngel

6
req.URL.RawQuerydevuelve todo después ?de una solicitud GET, si eso ayuda.
kouton

Lo encontré interesante req.Form es una matriz vacía a menos que req.formValue ("some_field") sea invocado al menos una vez.
Qian Chen

¡Gracias una tonelada! @kouton
Aditya Varma

127

Aquí hay un ejemplo más concreto de cómo acceder a los parámetros GET. El Requestobjeto tiene un método que los analiza por usted llamado Consulta :

Suponiendo una URL de solicitud como http: // host: puerto / algo? 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
  }    
}

También tenga en cuenta que "las claves en un mapa de valores [es decir, el valor de retorno de Query ()] distinguen entre mayúsculas y minúsculas".


4
Una respuesta anterior ya mencionada y vinculada a los documentos para hacer precisamente eso (y no tiene un ejemplo que entre en pánico con una referencia de corte fuera de los límites si el campo deseado no está presente, utilícelo r.URL.Query().Get("moviename")para evitar este error fatal).
Dave C

1
Gracias por la info. Sí, los documentos son un poco confusos para mí, así que publiqué esto como un "ejemplo práctico" en caso de que sea útil. Se corrigió el cheque nulo. El uso del Getmétodo solo devuelve el primero si hay varios, por lo que este es un ejemplo de más. Información útil, ¡gracias!
rogerdpack

Además, no creo que puedas comparar una cadena con nil: devs.cloudimmunity.com/gotchas-and-common-mistakes-in-go-golang es decir, string! = "" Es válido
James Milner

No creo que el código se compilaría, si el ejemplo estuviera completo. No puedes comparar la cadena vacía que Values.Get()regresa con nil. golang.org/pkg/net/url/#Values
Daniel Farrell

19

A continuación se muestra un ejemplo:

value := r.FormValue("field")

para más información. acerca del paquete http, puede visitar su documentación aquí . FormValuebásicamente devuelve valores POST o PUT, o valores GET, en ese orden, el primero que encuentra.


8

Aquí hay un ejemplo simple y funcional:

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)
}

ingrese la descripción de la imagen aquí



5

A continuación, las palabras provienen del documento oficial.

El formulario contiene los datos del formulario analizados, incluidos los parámetros de consulta del campo URL y los datos del formulario POST o PUT . Este campo solo está disponible después de llamar a ParseForm.

Por lo tanto, los códigos de muestra que se muestran a continuación funcionarían.

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
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.