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