Go HTTP服务器含文件与文本的Multipart表单提交时连接重置问题
问题分析与解决
你的代码存在两个核心问题,导致大文件上传时出现连接重置:
1. 表单未使用POST方法
HTML表单默认使用GET方法提交数据,但GET会将所有表单数据拼接在URL中,完全不适合处理包含大文件的multipart/form-data请求。当提交大文件时,服务器会因请求格式不符合规范直接重置连接,根本不会进入路由处理逻辑。
2. 路由路径不匹配
表单的action="/upload"与服务器注册的/upload/(带末尾斜杠)是两个不同的路径,Go的HTTP路由会严格匹配路径,因此即使请求方法正确,也会找不到对应的处理函数。
修正后的代码
package main import ( "fmt" "net/http" ) func showPage(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, `<!DOCTYPE html> <html> <body> <!-- 添加method="POST",并保证action与路由一致 --> <form enctype="multipart/form-data" action="/upload" method="POST"> <input type="file" name="file" /> <input type="text" name="lol" /> <input type="submit" value="upload" /> </form> </body> </html>`) } func uploadHandler(w http.ResponseWriter, r *http.Request) { // 解析multipart表单,设置内存缓存上限为10MB,超出部分写入临时文件 err := r.ParseMultipartForm(10 << 20) if err != nil { fmt.Println("解析表单失败:", err) w.WriteHeader(http.StatusBadRequest) fmt.Fprint(w, "表单解析失败") return } fmt.Println("yay!") fmt.Fprint(w, "yay!") } func main() { http.HandleFunc("/", showPage) // 去掉路由末尾的斜杠,与表单action保持一致 http.HandleFunc("/upload", uploadHandler) http.ListenAndServe(":8080", nil) }
额外说明
- 必须使用
POST方法处理文件上传,这是HTTP规范的要求,也是所有文件上传场景的标准做法。 - 调用
r.ParseMultipartForm可以显式解析表单数据,同时设置内存缓存大小能避免大文件上传导致的内存溢出问题。 - 修正后提交大文件,服务器会正常进入
uploadHandler,控制台打印yay!,页面也会显示对应内容。
内容的提问来源于stack exchange,提问作者LukeAtmi
相关产品推荐
相关产品推荐

