W pakiecie http Go, jak uzyskać ciąg zapytania w żądaniu POST?

114

Używam httppakietu z Idź do obsługi żądania POST. Jak uzyskać dostęp do ciągu zapytania z Requestobiektu i przeanalizować ją ? Nie mogę znaleźć odpowiedzi w oficjalnej dokumentacji.

Fabien
źródło
Należy pamiętać o jednej rzeczy, jeśli używasz cURL do wysyłania żądań i używasz r.FormValue("id")do pobierania parametrów zapytania, nie możesz wysłać i przez dane formularza w cURL (tj. curl 0.0.0.0:8888 -d id=foobarNie zadziała). Musisz go wysłać poprzez zapytanie params ( curl 0.0.0.0:8888?id=foobar).

Odpowiedzi:

145

QueryString z definicji znajduje się w adresie URL. Możesz uzyskać dostęp do adresu URL żądania za pomocą req.URL( doc ). Obiekt URL ma Query()metodę ( doc ), która zwraca Valuestyp, który jest po prostu jednym map[string][]stringz parametrów QueryString.

Jeśli szukasz danych POST przesłanych przez formularz HTML , to jest to (zwykle) para klucz-wartość w treści żądania. Masz rację w swojej odpowiedzi, że możesz zadzwonić, ParseForm()a następnie użyć req.Formpola, aby uzyskać mapę par klucz-wartość, ale możesz również zadzwonić, FormValue(key)aby uzyskać wartość określonego klucza. To wywołuje, ParseForm()jeśli jest to wymagane, i pobiera wartości niezależnie od tego, w jaki sposób zostały wysłane (tj. W ciągu zapytania lub w treści żądania).

mna
źródło
2
Dzięki za precyzję.
Fabien
2
Uważam, że metoda „req.FormValue (key)” jest szybsza i wykonuję za Ciebie cały kod potrzebny do wstępnej analizy adresu URL.
OnlyAngel
6
req.URL.RawQueryzwraca wszystko po ?żądaniu GET, jeśli to pomaga.
kouton
Wydaje mi się interesujące, że req.Form jest pustą tablicą, chyba że req.formValue ("some_field") jest wywoływana jednorazowo.
Qian Chen
Wielkie dzięki! @kouton
Aditya Varma
127

Oto bardziej konkretny przykład dostępu do parametrów GET. RequestObiekt ma metody, która przetwarza je na zadzwoniłeś Zapytanie :

Zakładając adres URL żądania, taki jak http: // host: port / coś? 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
  }    
}

Należy również zauważyć, że „w kluczach w mapie wartości [tj. Wartość zwracana przez Query ()] jest rozróżniana wielkość liter”.

rogerdpack
źródło
4
Poprzednia odpowiedź już wymienione i związane z docs robi tylko, że (i nie ma przykładu, który będzie paniki z poza granic pokroić odniesienie jeśli żądana pole nie jest obecny, stosowanie r.URL.Query().Get("moviename"), aby uniknąć tego fatalny błąd).
Dave C
1
Dzięki za informację. Tak, dokumenty są dla mnie trochę zagmatwane, więc opublikowałem to jako bardziej „przykładowe ręce”, na wypadek gdyby było przydatne. Naprawiono czek zerowy. Użycie tej Getmetody zwraca tylko pierwszą, jeśli istnieje wiele, więc jest to przykład more. Przydatne informacje, dziękuję!
rogerdpack
Nie sądzę również, aby można porównać ciąg do zera: devs.cloudimmunity.com/gotchas-and-common-mistakes-in-go-golang ie string! = „” Jest poprawne
James Milner
Nie sądzę, żeby kod się skompilował, gdyby przykład był kompletny. Nie możesz porównać pustego ciągu, który Values.Get()zwraca z nil. golang.org/pkg/net/url/#Values
Daniel Farrell
19

Poniżej przykład:

value := r.FormValue("field")

po więcej informacji. o pakiecie http, możesz odwiedzić jego dokumentację tutaj . FormValuezasadniczo zwraca wartości POST lub PUT lub wartości GET, w tej kolejności, w pierwszej znalezionej.

Muhammad Soliman
źródło
8

Oto prosty, działający przykład:

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

wprowadź opis obrazu tutaj

l3x
źródło
6

Istnieją dwa sposoby uzyskania parametrów zapytania:

  1. Korzystanie z reqeust.URL.Query ()
  2. Korzystanie z request.Form

W drugim przypadku należy zachować ostrożność, ponieważ parametry treści będą miały pierwszeństwo przed parametrami zapytania. Pełny opis uzyskiwania parametrów zapytania można znaleźć tutaj

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

user27111987
źródło
5

Poniższe słowa pochodzą z oficjalnego dokumentu.

Formularz zawiera przeanalizowane dane formularza, w tym parametry zapytania pola adresu URL oraz dane formularza POST lub PUT . To pole jest dostępne tylko po wywołaniu ParseForm.

Więc przykładowe kody jak poniżej będą działać.

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
źródło