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.

Fabien
fuente
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).

mna
fuente
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".

Rogerdpack
fuente
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.

Muhammad Soliman
fuente
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í

l3x
fuente
6

Hay dos formas de obtener parámetros de consulta:

  1. Usando reqeust.URL.Query ()
  2. Usando request.Form

En el segundo caso, hay que tener cuidado ya que los parámetros del cuerpo tendrán prioridad sobre los parámetros de consulta. Puede encontrar una descripción completa sobre cómo obtener parámetros de consulta aquí

https://golangbyexample.com/net-http-package-get-query-params-golang

usuario27111987
fuente
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
}
ChrisLee
fuente