Wie erhalte ich im http-Paket von Go die Abfragezeichenfolge für eine POST-Anforderung?

113

Ich verwende das httpPaket von Go, um die POST-Anfrage zu bearbeiten. Wie kann ich vom RequestObjekt aus auf den Inhalt der Abfragezeichenfolge zugreifen und diese analysieren ? Ich kann die Antwort aus der offiziellen Dokumentation nicht finden.

Fabien
quelle
Wenn Sie cURL zum Senden von Anforderungen und r.FormValue("id")zum Abrufen eines Abfrageparameters verwenden, können Sie i nicht über Formulardaten in cURL senden (dh curl 0.0.0.0:8888 -d id=foobares funktioniert nicht). Sie müssen es über query params ( curl 0.0.0.0:8888?id=foobar) senden .

Antworten:

144

Ein QueryString befindet sich per Definition in der URL. Sie können mit req.URL( doc ) auf die URL der Anfrage zugreifen . Das URL-Objekt verfügt über eine Query()Methode ( doc ), die einen ValuesTyp zurückgibt , der einfach einer map[string][]stringder QueryString-Parameter ist.

Wenn Sie nach den POST-Daten suchen, die von einem HTML-Formular übermittelt wurden , handelt es sich (normalerweise) um ein Schlüssel-Wert-Paar im Anforderungshauptteil. Sie haben die richtige Antwort, die Sie aufrufen ParseForm()und dann mithilfe des req.FormFelds die Karte der Schlüssel-Wert-Paare abrufen können. Sie können jedoch auch aufrufen FormValue(key), um den Wert eines bestimmten Schlüssels abzurufen. Dies ruft ParseForm()bei Bedarf auf und ruft Werte ab, unabhängig davon, wie sie gesendet wurden (dh in der Abfragezeichenfolge oder im Anforderungshauptteil).

mna
quelle
2
Danke für die Präzision.
Fabien
2
Ich finde die Methode 'req.FormValue (key)' schneller und erledige für Sie den gesamten erforderlichen Code, um die URL vorab zu analysieren.
OnlyAngel
6
req.URL.RawQuerygibt alles nach ?einer GET-Anfrage zurück, wenn das hilft.
Kouton
Ich fand es interessant, dass req.Form ein leeres Array ist, es sei denn, req.formValue ("some_field") wird mindestens einmal aufgerufen.
Qian Chen
Danke vielmals! @ Kouton
Aditya Varma
125

Hier ist ein konkreteres Beispiel für den Zugriff auf GET-Parameter. Das RequestObjekt verfügt über eine Methode, die sie für Sie analysiert : Abfrage :

Angenommen, eine Anforderungs-URL wie 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
  }    
}

Beachten Sie außerdem, dass bei den Schlüsseln in einer Wertezuordnung [dh dem Rückgabewert von Query ()] zwischen Groß- und Kleinschreibung unterschieden wird.

Rogerdpack
quelle
4
Eine frühere Antwort, die bereits erwähnt und mit den Dokumenten verknüpft wurde, um genau das zu tun (und es gibt kein Beispiel, das mit einer Slice-Referenz außerhalb der Grenzen in Panik gerät, wenn das gewünschte Feld nicht vorhanden ist. Verwenden Sie r.URL.Query().Get("moviename")diese Option, um diesen schwerwiegenden Fehler zu vermeiden).
Dave C
1
Danke für die Information. Ja, die Dokumente sind für mich etwas verwirrend, daher habe ich dies eher als "praktisches Beispiel" veröffentlicht, falls dies nützlich sein sollte. Der Null-Check wurde behoben. Die Verwendung der GetMethode gibt nur die erste zurück, wenn mehrere vorhanden sind. Dies ist also ein Beispiel für mehr. Nützliche Infos, danke!
Rogerdpack
Ich glaube auch nicht, dass Sie eine Zeichenfolge mit Null vergleichen können: devs.cloudimmunity.com/gotchas-and-common-mistakes-in-go-golang dh Zeichenfolge! = "" Ist gültig
James Milner
Ich glaube nicht, dass sich Code kompilieren würde, wenn das Beispiel vollständig wäre. Sie können die leere Zeichenfolge, Values.Get()mit der zurückgegeben wird, nicht vergleichen nil. golang.org/pkg/net/url/#Values
Daniel Farrell
19

Unten ist ein Beispiel:

value := r.FormValue("field")

Für mehr Information. Informationen zum http-Paket finden Sie in der Dokumentation hier . FormValueGrundsätzlich werden POST- oder PUT-Werte oder GET-Werte in dieser Reihenfolge zurückgegeben, der ersten, die gefunden wird.

Muhammad Soliman
quelle
8

Hier ist ein einfaches, funktionierendes Beispiel:

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

Geben Sie hier die Bildbeschreibung ein

l3x
quelle
6

Es gibt zwei Möglichkeiten, Abfrageparameter abzurufen:

  1. Verwenden von reqeust.URL.Query ()
  2. Verwenden von request.Form

Im zweiten Fall muss man vorsichtig sein, da Körperparameter Vorrang vor Abfrageparametern haben. Eine vollständige Beschreibung zum Abrufen von Abfrageparametern finden Sie hier

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

user27111987
quelle
5

Die folgenden Wörter stammen aus dem offiziellen Dokument.

Das Formular enthält die analysierten Formulardaten, einschließlich der Abfrageparameter des URL-Felds und der POST- oder PUT-Formulardaten . Dieses Feld ist nur verfügbar, nachdem ParseForm aufgerufen wurde.

Beispielcodes wie unten würden also funktionieren.

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
quelle