How To Make Http Url Form Encoded Request Golang
Alex Garella
27 April 2022
A POST request is typically sent via a HTML web form and there may be different content types which you can use to send such request. Let’s see the various types you can use when sending a POST request via HTML form
application/x-www-form-urlencoded
: the keys and values are encoded in key-value tuples separated by'&'
, with a'='
between the key and the value. Non-alphanumeric characters in both keys and values are percent encoded (check out how to url encode a string in Go): this is the reason why this type is not suitable to use with binary data (usemultipart/form-data
instead)multipart/form-data
: each value is sent as a block of data (“body part”), with a user agent-defined delimiter (“boundary”) separating each part. The keys are given in theContent-Disposition
header of each part.text/plain
In this article we are going to see how to send a POST request using a application/x-www-form-urlencoded
content type using Golang.
Creating a url form encoded request in Golang is straightforward especially when using the methods that comes directly from Go’s standard library.
One of the key struct we are going to use for this is url,Values
Values maps a string key to a list of values. It is typically used for query parameters and form values. Unlike in the http.Header map, the keys in a Values map are case-sensitive.
This is a simple way we can wrap up different key-value pairs together when building a url formencoded POST request. This is particularly easy because the url package provides already an Encode method which we can use out of the box to percent encode our key-value pairs url.Values.Encode()
func (v Values) Encode() string
Encode encodes the values into “URL encoded” form (“bar=baz&foo=quux”) sorted by key.
URL form encoded request example
Now let’s see a concrete example on how we can send a url form encoded request in Go (Golang)
package main
import (
"net/http"
"net/url"
"strconv"
"strings"
"log"
"io/ioutil"
)
func main() {
endpoint := "http://example.com/submit_form.php"
data := url.Values{}
data.Set("foo", "bar")
data.Set("bar", "baz")
client := &http.Client{}
r, err := http.NewRequest("POST", endpoint, strings.NewReader(data.Encode())) // URL-encoded payload
if err != nil {
log.Fatal(err)
}
r.Header.Add("Content-Type", "application/x-www-form-urlencoded")
r.Header.Add("Content-Length", strconv.Itoa(len(data.Encode())))
res, err := client.Do(r)
if err != nil {
log.Fatal(err)
}
log.Println(res.Status)
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
log.Fatal(err)
}
log.Println(string(body))
}