go版本: go1.22.2
server文件:
package main
import (
"fmt"
"io"
"net/http"
"os"
"time"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("hello world"))
})
http.HandleFunc("/upload", func(w http.ResponseWriter, r *http.Request) {
r.ParseMultipartForm(10 << 20) // 限制上传文件最大10M
f, fh, err := r.FormFile("hello")
fmt.Println("r.FormFile f: ", f)
fmt.Println("r.FormFile fh: ", fh)
fmt.Println("r.FormFile err: ", err)
if err != nil {
http.Error(w, "r.FormFile err: "+err.Error(), http.StatusBadRequest)
return
}
filename := fmt.Sprintf("%d-hello.txt", time.Now().Unix())
fw, err := os.OpenFile(filename, os.O_CREATE, 0666)
if err != nil {
fmt.Println("os.OpenFile err: ", err)
http.Error(w, "os.OpenFile err: "+err.Error(), http.StatusBadRequest)
return
}
_, err = io.Copy(fw, f)
if err != nil {
fmt.Println("io.Copy err: ", err)
http.Error(w, "io.Copy err: "+err.Error(), http.StatusBadRequest)
return
}
fw.Close()
f.Close()
w.Write([]byte("ok"))
fmt.Fprint(w, "finished")
})
http.ListenAndServe(":8000", nil)
}
client文件:
package main
import (
"bytes"
"fmt"
"io"
"mime/multipart"
"net/http"
"os"
)
func main() {
buf := bytes.Buffer{}
wr := multipart.NewWriter(&buf)
fieldname := "hello" // 字段名
filename := "hello.txt" // 文件名
fw, err := wr.CreateFormFile(fieldname, filename)
if err != nil {
fmt.Println("wr.CreateFormFile err: ", err)
return
}
fr, err := os.Open(filename)
if err != nil {
fmt.Println("os.Open err: ", err)
return
}
_, err = io.Copy(fw, fr)
if err != nil {
fmt.Println("io.Copy err: ", err)
return
}
// -----------------------
// 创建form和发送请求在同一个函数中,如果这样写会,服务端报错:multipart: NextPart: EOF
// defer wr.Close()
// -----------------------
fr.Close()
wr.Close()
// -----------------------
// 发送请求
link := "http://127.0.0.1:8000/upload"
request, err := http.NewRequest(http.MethodPost, link, &buf)
if err != nil {
fmt.Println("http.NewRequest err: ", err)
return
}
// 设置header
request.Header.Set("Content-Type", wr.FormDataContentType())
client := http.Client{}
response, err := client.Do(request)
if err != nil {
fmt.Println("client.Do err: ", err)
return
}
defer response.Body.Close()
result, err := io.ReadAll(response.Body)
fmt.Println(string(result), err)
}
# 报错信息
multipart: NextPart: EOF
# 上述代码说明
......
// -----------------------
// 创建form和发送请求在同一个函数中,如果这样写会,服务端报错:multipart: NextPart: EOF
// defer wr.Close()
// -----------------------
fr.Close()
wr.Close()
// -----------------------
......
hello.txt文件:
hello world
执行文件:
# 服务端
go run server.go
# 客户端
go run client.go