html - 尽管表单有效,但 ParseMultipartForm 总是失败
问题描述
我正在尝试在 go http 服务器中处理上传的文件。但是调用ParseMultipartForm总是失败并出现奇怪的错误:“ multipart: NextPart: EOF ” 尽管表单是有效的。调试它,我可以看到我得到了完整的编码数据、大小和参数。然而它无法解析。
这是html表单:
<html>
<head>
<title>Upload file</title>
</head>
<body>
<form enctype="multipart/form-data" action="http://localhost:8080/uploadLogo/" method="post">
<input type="file" name="uploadfile" />
<input type="hidden" name="token" value="{{.}}" />
<input type="submit" value="upload" />
</form>
</body>
</html>
这是相关的上传功能:
// upload logic
func upload(w http.ResponseWriter, r *http.Request) {
fmt.Println("method:", r.Method)
if r.Method == "GET" {
// crutime := time.Now().Unix()
// h := md5.New()
// io.WriteString(h, strconv.FormatInt(crutime, 10))
// token := fmt.Sprintf("%x", h.Sum(nil))
// t, _ := template.ParseFiles("upload.gtpl")
// t.Execute(w, token)
} else {
err := r.ParseMultipartForm(5 * 1024 * 1024 * 1024)
if err != nil {
fmt.Println("Error ParseMultipartForm: ", err) // here it fails !!! with: "multipart: NextPart: EOF"
return
}
file, handler, err := r.FormFile("uploadfile")
if err != nil {
fmt.Println("Error parsing file", err)
return
}
defer file.Close()
fmt.Fprintf(w, "%v", handler.Header)
fmt.Println("filename:", handler.Filename)
f, err := os.OpenFile(logosDir + handler.Filename, os.O_WRONLY|os.O_CREATE, 0666)
if err != nil {
fmt.Println(err)
return
}
defer f.Close()
io.Copy(f, file)
}
}
无法理解为什么会这样。
这是我启动服务器的方式:
func uploadLogoHandler(w http.ResponseWriter, r *http.Request) {
//fmt.Fprintf(w, "viewLogoHandler, Path: %s!", r.URL.Path[1:])
bodyBytes, _ := ioutil.ReadAll(r.Body)
bodyString := string(bodyBytes)
writeToLog("uploadLogoHandler:" + r.URL.Path, "bodyString length:" + strconv.Itoa(len(bodyString)))
upload(w, r)
}
///////////////////////////////////////////////////////////////////////////////////////
// main
func main() {
if(len(os.Args) < 2) {
fmt.Println("Usage: receiver [port number]")
os.Exit(1)
}
port := os.Args[1]
s := &http.Server{
Addr: ":" + port,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
}
http.HandleFunc("/uploadLogo/", uploadLogoHandler)
http.HandleFunc("/", handler)
log.Fatal(s.ListenAndServe())
}
解决方案
在写这个问题时,我已经发现了问题。它在句柄函数中。我在调用上传函数之前读取了所有流数据。这是处理程序的修改代码,现在一切正常:
func uploadLogoHandler(w http.ResponseWriter, r *http.Request) {
writeToLog("uploadLogoHandler:" + r.URL.Path, "")
upload(w, r)
}
如果我理解正确,那么错误:“multipart:NextPart:EOF”表示表单为空 - 它是空的,因为我之前清空了缓冲区流。
希望它会帮助别人。最好的。
推荐阅读
- go - 霍夫曼编码导致错误的输出但正确的长度
- c# - 如何在 C# 中正确使用 CreateTextServices、ITextHost?
- swift - 便利初始化程序不断崩溃,但指定的初始化程序工作正常?
- python - 如果我得到一个 Qt 小部件的 Python 实例,有没有办法导出/复制它?
- c++ - 根据模板类型生成 lambdas 主体(调用可调用对象并返回)
- mysql - 使用不同的脚本创建 If 分支
- sql-server - 多个数据源的 Spring Boot 问题
- jquery - 在将图像获取为 encode64 时删除 encode64 标头数据。?
- r - 如何找到不同年龄组的信用卡持有人百分比
- firebase - 如何在应用程序的二进制文件中捆绑默认的 ML 人脸模型?