Как в HTTP-пакете Go получить строку запроса в запросе POST?

114

Я использую httpпакет от Go для обработки запроса POST. Как я могу получить доступ и проанализировать содержимое строки запроса из Requestобъекта? Я не могу найти ответ в официальной документации.

Fabien
источник
Следует иметь в виду, что если вы используете cURL для отправки запросов и используете r.FormValue("id")для получения параметра запроса, вы не можете отправлять i через данные формы в cURL (т. Е. curl 0.0.0.0:8888 -d id=foobarНе будет работать). Вы должны отправить его через query params ( curl 0.0.0.0:8888?id=foobar).

Ответы:

145

QueryString по определению находится в URL-адресе. Вы можете получить доступ к URL-адресу запроса, используя req.URL( doc ). У объекта URL есть Query()метод ( doc ), который возвращает Valuesтип, который является просто одним map[string][]stringиз параметров QueryString.

Если вы ищете данные POST, отправленные HTML-формой , то это (обычно) пара ключ-значение в теле запроса. Вы правы в своем ответе, который вы можете вызвать, ParseForm()а затем использовать req.Formполе для получения карты пар ключ-значение, но вы также можете позвонить, FormValue(key)чтобы получить значение определенного ключа. Он вызывает, ParseForm()если требуется, и получает значения независимо от того, как они были отправлены (то есть в строке запроса или в теле запроса).

МНО
источник
2
Спасибо за точность.
Fabien
2
Я нахожу метод req.FormValue (key) более быстрым и делаю для вас весь необходимый код для предварительного анализа URL-адреса.
OnlyAngel
6
req.URL.RawQueryвозвращает все, что находится после ?запроса GET, если это помогает.
kouton 01
Мне показалось интересным, что req.Form - пустой массив, если только req.formValue ("some_field") не вызывается при аренде один раз.
Цянь Чен
Благодаря тонну! @kouton
Адитья Варма
127

Вот более конкретный пример того, как получить доступ к параметрам GET. У Requestобъекта есть метод, который их анализирует для вас, который называется Query :

Предполагая URL-адрес запроса, например 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
  }    
}

Также обратите внимание, что «ключи в карте значений [т.е. возвращаемое значение Query ()] чувствительны к регистру».

rogerdpack
источник
4
Предыдущий ответ уже упоминалось и в связи с Документами ведения только что (и это не пример , который будет паниковать с вне границ порезать ссылку , если искомое поле нет, использование , r.URL.Query().Get("moviename")чтобы избежать этой роковой ошибки).
Dave C
1
Спасибо за информацию. Да, документы меня немного сбивают с толку, поэтому я разместил это как «практический пример» на всякий случай. Исправлена ​​проверка нуля. Использование Getметода возвращает только первое, если их несколько, так что это пример большего количества. Полезная инфа, спасибо!
rogerdpack
Также я не думаю, что вы можете сравнивать строку с nil: devs.cloudimmunity.com/gotchas-and-common-mistakes-in-go-golang т.е. строка! = "" Действительна
Джеймс Милнер,
Я не думаю, что этот код мог бы компилироваться, если бы пример был готов. Вы не можете сравнить Values.Get()возвращаемую пустую строку с nil. golang.org/pkg/net/url/#Values
Дэниел Фаррелл,
19

Ниже приведен пример:

value := r.FormValue("field")

для получения дополнительной информации. о http-пакете вы можете посмотреть его документацию здесь . FormValueв основном возвращает значения POST или PUT или значения GET в этом порядке, первое найденное.

Мухаммад Солиман
источник
8

Вот простой рабочий пример:

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

введите описание изображения здесь

l3x
источник
6

Есть два способа получить параметры запроса:

  1. Использование reqeust.URL.Query ()
  2. Использование request.Form

Во втором случае нужно быть осторожным, поскольку параметры тела будут иметь приоритет над параметрами запроса. Полное описание получения параметров запроса можно найти здесь

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

user27111987
источник
5

Ниже приведены слова из официального документа.

Форма содержит проанализированные данные формы, включая параметры запроса поля URL и данные формы POST или PUT . Это поле доступно только после вызова ParseForm.

Итак, примеры кодов, показанные ниже, будут работать.

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
источник