Dans le package http de Go, comment obtenir la chaîne de requête sur une requête POST?

114

J'utilise le httppackage de Go pour traiter la demande POST. Comment puis-je accéder et analyser le contenu de la chaîne de requête à partir de l' Requestobjet? Je ne trouve pas la réponse dans la documentation officielle.

Fabien
la source
Une chose à garder à l'esprit, si vous utilisez cURL pour envoyer des requêtes et que vous utilisez r.FormValue("id")pour récupérer un paramètre de requête, vous ne pouvez pas envoyer i via des données de formulaire dans cURL (c'est-à-dire que curl 0.0.0.0:8888 -d id=foobarcela ne fonctionnera pas). Vous devez l'envoyer via query params ( curl 0.0.0.0:8888?id=foobar).

Réponses:

145

Une QueryString est, par définition , dans l'URL. Vous pouvez accéder à l'URL de la requête en utilisant req.URL( doc ). L'objet URL a une Query()méthode ( doc ) qui renvoie un Valuestype, qui est simplement un map[string][]stringdes paramètres QueryString.

Si vous recherchez les données POST soumises par un formulaire HTML , il s'agit (généralement) d'une paire clé-valeur dans le corps de la requête. Vous avez raison dans votre réponse que vous pouvez appeler ParseForm(), puis utiliser req.Formfield pour obtenir la carte des paires clé-valeur, mais vous pouvez également appeler FormValue(key)pour obtenir la valeur d'une clé spécifique. Cela appelle ParseForm()si nécessaire et obtient des valeurs indépendamment de la façon dont elles ont été envoyées (c'est-à-dire dans la chaîne de requête ou dans le corps de la requête).

mna
la source
2
Merci pour les précisions.
Fabien
2
Je trouve la méthode 'req.FormValue (key)' plus rapide et je fais pour vous tout le code nécessaire pour pré-analyser l'url.
OnlyAngel
6
req.URL.RawQueryrenvoie tout après le ?sur une requête GET, si cela vous aide.
kouton
Je l'ai trouvé intéressant req.Form est un tableau vide à moins que req.formValue ("some_field") ne soit invoqué en une seule fois.
Qian Chen
Merci beaucoup! @kouton
Aditya Varma
127

Voici un exemple plus concret de la façon d'accéder aux paramètres GET. L' Requestobjet a une méthode qui les analyse pour vous appelée Query :

En supposant une URL de requête comme http: // hôte: port / quelque chose? 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
  }    
}

Notez également que «les clés d'une mappe de valeurs [c'est-à-dire la valeur de retour de Query ()] sont sensibles à la casse».

rogerdpack
la source
4
Une réponse précédente déjà mentionnée et liée à la documentation de faire exactement cela (et il n'y a pas d'exemple qui paniquera avec une référence de tranche hors limites si le champ souhaité n'est pas présent, utilisez r.URL.Query().Get("moviename")pour éviter cette erreur fatale).
Dave C
1
Merci pour l'info. Ouais, les documents sont un peu déroutants pour moi, donc j'ai posté cela comme un "exemple pratique" au cas où cela serait utile. Correction du chèque nul. L'utilisation de la Getméthode ne renvoie le premier que s'il y en a plusieurs, c'est donc un exemple de plus. Infos utiles, merci!
rogerdpack
De plus, je ne pense pas que vous puissiez comparer une chaîne à nil: devs.cloudimmunity.com/gotchas-and-common-mistakes-in-go-golang ie string! = "" Est valide
James Milner
Je ne pense pas que ce code se compilerait si l'exemple était complet. Vous ne pouvez pas comparer la chaîne vide qui Values.Get()renvoie avec nil. golang.org/pkg/net/url/#Values
Daniel Farrell
19

Voici un exemple:

value := r.FormValue("field")

pour plus d'informations. à propos du package http, vous pouvez visiter sa documentation ici . FormValuerenvoie essentiellement les valeurs POST ou PUT, ou les valeurs GET, dans cet ordre, le premier qu'il trouve.

Muhammad Soliman
la source
8

Voici un exemple simple et fonctionnel:

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

entrez la description de l'image ici

l3x
la source
6

Il existe deux façons d'obtenir les paramètres de requête:

  1. Utilisation de reqeust.URL.Query ()
  2. Utilisation de request.Form

Dans le second cas, il faut être prudent car les paramètres de corps auront la priorité sur les paramètres de requête. Une description complète de l'obtention des paramètres de requête peut être trouvée ici

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

utilisateur27111987
la source
5

Les mots ci-dessous proviennent du document officiel.

Le formulaire contient les données du formulaire analysées, y compris les paramètres de requête du champ URL et les données du formulaire POST ou PUT . Ce champ n'est disponible qu'après l'appel de ParseForm.

Ainsi, des exemples de codes comme ci-dessous fonctionneraient.

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
la source