No pacote http do Go, como obtenho a string de consulta em uma solicitação POST?

114

Estou usando o httppacote do Go para lidar com a solicitação POST. Como posso acessar e analisar o conteúdo da string de consulta do Requestobjeto? Não consigo encontrar a resposta na documentação oficial.

Fabien
fonte
Uma coisa a ter em mente: se você estiver usando cURL para enviar solicitações e r.FormValue("id")buscar um parâmetro de consulta, não poderá enviar i por meio de dados de formulário em cURL (ou seja, curl 0.0.0.0:8888 -d id=foobarnão funcionará). Você deve enviá-lo através de parâmetros de consulta ( curl 0.0.0.0:8888?id=foobar).

Respostas:

145

Um QueryString está, por definição , no URL. Você pode acessar a URL da solicitação usando req.URL( doc ). O objeto URL possui um Query()método ( doc ) que retorna um Valuestipo, que é simplesmente um map[string][]stringdos parâmetros QueryString.

Se o que você está procurando são os dados POST enviados por um formulário HTML , então este é (geralmente) um par de valores-chave no corpo da solicitação. Você está correto em sua resposta que pode chamar ParseForm()e usar o req.Formcampo para obter o mapa de pares de valores-chave, mas também pode chamar FormValue(key)para obter o valor de uma chave específica. Isso chama ParseForm()se necessário e obtém os valores independentemente de como foram enviados (ou seja, na string de consulta ou no corpo da solicitação).

mna
fonte
2
Obrigado pelas precisões.
Fabien
2
Eu acho o método 'req.FormValue (key)' mais rápido e faço para você todo o código necessário para pré-analisar a url.
OnlyAngel
6
req.URL.RawQueryretorna tudo após ?em uma solicitação GET, se isso ajudar.
kouton 01 de
Achei interessante req.Form is empty array, a menos que req.formValue ("some_field") seja invocado pelo menos uma vez.
Qian Chen
Muito obrigado! @kouton
Aditya Varma
127

Aqui está um exemplo mais concreto de como acessar os parâmetros GET. O Requestobjeto tem um método que os analisa para você, chamado Query :

Presumindo um URL de solicitação como 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
  }    
}

Observe também que "as chaves em um mapa Values ​​[isto é, valor de retorno Query ()] diferenciam maiúsculas de minúsculas."

rogerdpack
fonte
4
Uma resposta anterior já mencionada e vinculada aos documentos de fazer exatamente isso (e não tem um exemplo que entrará em pânico com uma referência de fatia fora dos limites se o campo desejado não estiver presente, use r.URL.Query().Get("moviename")para evitar esse erro fatal).
Dave C
1
Obrigado pela informação. Sim, os documentos são um pouco confusos para mim, então postei isso mais como um "exemplo prático", caso seja útil. Corrigido o cheque nulo. Usar o Getmétodo só retorna o primeiro se houver vários, então este é um exemplo de mais. Informação útil, obrigado!
rogerdpack
Além disso, não acho que você pode comparar uma string com nil: devs.cloudimmunity.com/gotchas-and-common-mistakes-in-go-golang ie string! = "" É válido
James Milner
Eu não acho que o código iria compilar, se o exemplo estivesse completo. Você não pode comparar a string vazia que Values.Get()retorna com nil. golang.org/pkg/net/url/#Values
Daniel Farrell
19

Abaixo está um exemplo:

value := r.FormValue("field")

para mais informações. sobre o pacote http, você pode visitar sua documentação aqui . FormValuebasicamente retorna valores POST ou PUT, ou valores GET, nessa ordem, o primeiro que encontrar.

Muhammad Soliman
fonte
8

Aqui está um exemplo simples e 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)
}

insira a descrição da imagem aqui

13x
fonte
6

Existem duas maneiras de obter parâmetros de consulta:

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

No segundo caso, deve-se ter cuidado, pois os parâmetros do corpo terão precedência sobre os parâmetros de consulta. Uma descrição completa sobre como obter parâmetros de consulta pode ser encontrada aqui

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

user27111987
fonte
5

As palavras abaixo vêm do documento oficial.

O formulário contém os dados do formulário analisados, incluindo os parâmetros de consulta do campo URL e os dados do formulário POST ou PUT . Este campo só está disponível após a chamada de ParseForm.

Portanto, os códigos de amostra abaixo funcionariam.

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
fonte