接收端
首先我们有这样一段测试代码来接收 POST 请求,并返回其接收到的字段信息。
1package main
2
3import (
4 "fmt"
5 "log"
6 "net/http"
7)
8
9func urlencodedHandler(w http.ResponseWriter, r *http.Request) {
10 err := r.ParseForm()
11 if err != nil {
12 log.Printf("r.ParseForm(): %v", err)
13 return
14 }
15
16 result := ""
17 for k, v := range r.Form {
18 result += fmt.Sprintf("%s:%v\n", k, v)
19 }
20
21 fmt.Fprintf(w, result)
22}
23
24func multipartHandler(w http.ResponseWriter, r *http.Request) {
25 err := r.ParseMultipartForm(4 * 1024 * 1024)
26 if err != nil {
27 log.Printf("r.ParseForm(): %v", err)
28 return
29 }
30
31 result := ""
32 for k, v := range r.MultipartForm.Value {
33 result += fmt.Sprintf("%s:%v\n", k, v)
34 }
35
36 for k, v := range r.MultipartForm.File {
37 result += fmt.Sprintf("%s:%v\n", k, v)
38 }
39
40 fmt.Fprintf(w, result)
41}
42
43func main() {
44 http.HandleFunc("/urlencoded", urlencodedHandler)
45 http.HandleFunc("/multipart", multipartHandler)
46
47 log.Fatal(http.ListenAndServe(":8080", nil))
48}
发送 urlencoded 请求
urlencoded
主要用于纯文本请求,代码如下:
1package main
2
3import (
4 "fmt"
5 "io/ioutil"
6 "net/http"
7 "net/url"
8 "strings"
9)
10
11func main() {
12 payload := url.Values{}
13 payload.Set("foo", "a")
14 payload.Add("foo", "b")
15 payload.Set("foo2", "c")
16
17 req, err := http.NewRequest(http.MethodPost,
18 "http://localhost:8080/urlencoded",
19 strings.NewReader(payload.Encode()))
20 if err != nil {
21 return
22 }
23
24 req.Header.Add("Content-Type",
25 "application/x-www-form-urlencoded; param=value")
26
27 resp, err := http.DefaultClient.Do(req)
28 if err != nil {
29 return
30 }
31
32 defer resp.Body.Close()
33
34 data, _ := ioutil.ReadAll(resp.Body)
35
36 fmt.Println(string(data))
37}
运行 go run urlencoded.go
输出结果为:
1foo2:[c]
2foo:[a b]
发送 multipart 请求
multipart
主要用于发送文件上传的请求,代码如下:
1package main
2
3import (
4 "bytes"
5 "fmt"
6 "io/ioutil"
7 "log"
8 "mime/multipart"
9 "net/http"
10)
11
12func main() {
13 buf := new(bytes.Buffer)
14
15 writer := multipart.NewWriter(buf)
16 writer.WriteField("foo", "a")
17 writer.WriteField("foo", "b")
18
19 part, err := writer.CreateFormFile("tmp.png", "tmp.png")
20 if err != nil {
21 return
22 }
23
24 fileData := []byte("hello,world") // 此处内容可以来自本地文件读取或云存储
25 part.Write(fileData)
26
27 if err = writer.Close(); err != nil {
28 return
29 }
30
31 req, err := http.NewRequest(http.MethodPost,
32 "http://localhost:8080/multipart",
33 buf)
34 if err != nil {
35 return
36 }
37
38 req.Header.Add("Content-Type", writer.FormDataContentType())
39
40 resp, err := http.DefaultClient.Do(req)
41 if err != nil {
42 return
43 }
44
45 defer resp.Body.Close()
46
47 data, _ := ioutil.ReadAll(resp.Body)
48
49 fmt.Println(string(data))
50}
运行 go run multipart.go
输出结果为:
1foo:[a b]
2tmp.png:[0xc420082410]
除另有声明外,本博客文章均采用 知识共享 (Creative Commons) 署名 4.0 国际许可协议 进行许可。转载请注明原作者与文章出处。