You may use HTML forms to upload data, especially when uploading binary resources (such as images, videos, etc.). We usually use two content-types of forms. The first is the multipart/form-data format that we use a lot now. Another is Application/X-www-form-urlencoded (similar to the Query parameter in THE URL). This article focuses on both formats and how to manipulate them using http.Request objects in the Go language (with many subtle differences).
Two Form formats
application/x-www-form-urlencoded
From the name of the format, we can infer that it is encoded using the URL, but we can also customize the Form encoding rules by specifying accept-charset. It can only accept text data with a simple structure (it cannot be nested in multiple layers like JSON), so it is now commonly used instead in the Application/JSON format. Here is a simple example of this format:
/test1 prints Body directly, while /test2 prints Go application/ X-www-form-urlencoded operations
package main
import (
"fmt"
"io"
"net/http"
)
func main(a) {
mux := http.NewServeMux()
mux.HandleFunc("/test1".func(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
defer r.Body.Close()
iferr ! =nil {
return
}
fmt.Println(string(body))
})
mux.HandleFunc("/test2".func(w http.ResponseWriter, r *http.Request) {
iferr := r.ParseForm(); err ! =nil {
return
}
fmt.Println(r.Form)
fmt.Println(r.PostForm)
fmt.Println(r.FormValue("name"))
fmt.Println(r.FormValue("age"))
fmt.Println(r.PostFormValue("name"))
fmt.Println(r.PostFormValue("age"))
})
server := &http.Server{
Addr: "127.0.0.1:8080",
Handler: mux,
}
server.ListenAndServe()
}
Copy the code
The request format is as follows:
Print when using test1: As you can see, this is the format that encodes the table as a URL, so it can be said to be the Body Query parameter
FormValue() reads the contents of the Body and URL, and PostFormValue() reads the contents of the Body.
multipart/form-data
So this is the type that we’re using a lot, and it’s used to upload images, videos, etc., and it’s encoded to specify the type and filename of the resource, Compared to Application/X-www-form-urlencoded, it is less efficient (because it requires more characters to represent different types of data), but it can support binary format content such as images, videos, etc. It is generally recommended to use it when uploading static resources. Here is a simple example:
As above, /test1 prints the Body directly, while /test2 prints the Go multipart/form-data operations
package main
import (
"fmt"
"io"
"net/http"
)
func main(a) {
mux := http.NewServeMux()
mux.HandleFunc("/test1".func(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
defer r.Body.Close()
iferr ! =nil {
return
}
fmt.Println(string(body))
})
mux.HandleFunc("/test2".func(w http.ResponseWriter, r *http.Request) {
if err := r.ParseMultipartForm(1024); err ! =nil {
return
}
fmt.Println(r.Form)
fmt.Println(r.PostForm)
fmt.Println(r.FormValue("name"))
fmt.Println(r.FormValue("age"))
fmt.Println(r.PostFormValue("name"))
fmt.Println(r.PostFormValue("age"))
fmt.Println(r.MultipartForm)
fmt.Println(r.FormFile("avatar"))
})
server := &http.Server{
Addr: "127.0.0.1:8080",
Handler: mux,
}
server.ListenAndServe()
}
Copy the code
The request format is as follows:
Print when using test1: As you can see is a less space-saving way of encoding, space each field at —————————-965042754073201157943416 and then on the following line content-Disposition: form-data; Name =”age”; name=”age”; name=”age”; For binary files, filename=”381056168614065362.png” is used to indicate the original filename (so that we can get the original filename from the server interface). For text fields, the next line is the text content; For binary files, the next line is followed by binary content.
Print when using test2: As you can see, The Go language Request operation that applies to Application/X-www-form-urlencoded also applies to multipart/form-data (so multipart/form-data can be considered applicati that supports binary types On /x-www-form-urlencoded), and MultipartForm itself reads only Body content like PostForm, but MultipartForm also reads binary fields. FormFile() obviously just fetches the contents of the file type in the Body.
conclusion
Go language operation | The parsing operation | Read the URL | Read the Body (form) | Supports text | Binary support |
---|---|---|---|---|---|
Form | ParseForm() | is | is | is | |
PostForm | ParseForm() | is | is | ||
FormValue() | Automatically call ParseForm() | is | is | is | |
PostFormValue() | Automatically call ParseForm() | is | is | ||
MultipartForm | ParseMultipartForm() | is | is | is | |
FormFile() | Automatically call ParseMultipartForm | is | is |