在 Web 開發中,文件上傳?是常見需求,例如頭像上傳、文檔存儲、圖片分享等功能。Go 語言的標準庫?
net/http
?已經內置了對?multipart/form-data
?類型的支持,能讓我們輕松構建一個文件上傳服務。
本文將帶你實現一個可運行的文件上傳接口,并附帶 HTML 表單和?curl
?測試方法。
一、目標功能
- ? 路徑:
/upload
- ? 方法:
POST
- ? 表單字段:
- ??
file
:上傳文件 - ??
desc
:文件描述(可選)
- ??
- ? 保存文件到本地?
./uploads
?目錄 - ? 返回 JSON 結果
二、核心知識點
- ??
r.ParseMultipartForm(maxMemory)
:解析?multipart/form-data
?表單 - ??
r.FormFile("file")
:獲取上傳的文件 - ??
io.Copy(dst, src)
:保存文件到本地 - ? 表單字段獲取:
r.FormValue("desc")
- ? 文件權限控制:
os.Create()
?/?os.MkdirAll()
三、完整代碼
package?mainimport?("encoding/json""fmt""io""net/http""os""path/filepath"
)type?UploadResponse?struct?{Filename?string?`json:"filename"`Size?????int64??`json:"size"`Desc?????string?`json:"desc"`Status???string?`json:"status"`
}func?uploadHandler(w?http.ResponseWriter,?r?*http.Request)?{if?r.Method?!=?http.MethodPost?{http.Error(w,?"Method?Not?Allowed",?http.StatusMethodNotAllowed)return}//?解析上傳表單(maxMemory?5MB,超過部分存臨時文件)err?:=?r.ParseMultipartForm(5?<<?20)if?err?!=?nil?{http.Error(w,?"Error?parsing?form:?"+err.Error(),?http.StatusBadRequest)return}//?獲取表單字段desc?:=?r.FormValue("desc")//?獲取文件file,?handler,?err?:=?r.FormFile("file")if?err?!=?nil?{http.Error(w,?"Error?retrieving?file:?"+err.Error(),?http.StatusBadRequest)return}defer?file.Close()//?確保保存目錄存在os.MkdirAll("./uploads",?os.ModePerm)//?保存文件filePath?:=?filepath.Join("uploads",?handler.Filename)dst,?err?:=?os.Create(filePath)if?err?!=?nil?{http.Error(w,?"Error?saving?file:?"+err.Error(),?http.StatusInternalServerError)return}defer?dst.Close()size,?err?:=?io.Copy(dst,?file)if?err?!=?nil?{http.Error(w,?"Error?writing?file:?"+err.Error(),?http.StatusInternalServerError)return}//?返回?JSON?響應w.Header().Set("Content-Type",?"application/json")json.NewEncoder(w).Encode(UploadResponse{Filename:?handler.Filename,Size:?????size,Desc:?????desc,Status:???"success",})
}func?main()?{http.HandleFunc("/upload",?uploadHandler)fmt.Println("文件上傳服務已啟動:http://localhost:8080/upload")http.ListenAndServe(":8080",?nil)
}
四、測試方法
1. HTML 表單測試
保存為?upload.html
:
<!DOCTYPE?html>
<html>
<body>
<h2>文件上傳測試</h2>
<form?action="http://localhost:8080/upload"?method="post"?enctype="multipart/form-data">文件描述:?<input?type="text"?name="desc"><br><br>選擇文件:?<input?type="file"?name="file"><br><br><input?type="submit"?value="上傳">
</form>
</body>
</html>
打開瀏覽器選擇文件并提交。
2. curl 命令測試
curl?-X?POST?http://localhost:8080/upload?\-F?"desc=測試圖片"?\-F?"file=@test.png"
五、運行效果
成功上傳后返回:
{"filename":?"test.png","size":?15324,"desc":?"測試圖片","status":?"success"
}
文件會保存在?./uploads/test.png
。
六、注意事項
- 1.?上傳限制:
通過?r.ParseMultipartForm(maxMemory)
?控制內存占用,超過部分會寫入臨時文件。 - 2.?安全性:
- ? 校驗文件類型(避免執行惡意文件)
- ? 生成唯一文件名(避免覆蓋)
- ? 設置合理的文件大小限制(可用?
http.MaxBytesReader
)
- 3.?跨域請求:
如果前端與后端不在同一域名,需要設置?Access-Control-Allow-Origin
?等 CORS 頭。
七、進階擴展
- ? 上傳時自動生成文件唯一 ID(防止文件名沖突)
- ? 返回文件訪問 URL
- ? 將文件上傳到云存儲(如 AWS S3、阿里云 OSS)
- ? 支持多文件同時上傳(
r.MultipartForm.File["file"]
)