本文为原创, 遵循 CC 4.0 BY-SA 版权协议, 转载需注明出处: https://blog.csdn.net/big_cheng/article/details/120095982.
文中代码属于 public domain (无版权).
以Golang webapp为例.
html
https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/Input/file
https://developer.mozilla.org/zh-CN/docs/Web/API/File
if (document.getElementById('file1').files[0].size > 1024*1024) {
// 文件超过1M
}
https://developer.mozilla.org/zh-CN/docs/Web/API/FormData/append
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#uploading_a_file
使用FormData 上传文件到服务器.
nginx
server {
...
client_max_body_size 210K;
location = /upload {
...
client_max_body_size 1034K;
}
...
}
1034K = 文件1M + 请求体part的分隔符(10K, 按1%). 如果还有其他part(普通Form字段), 也需加上.
net/http Handler
func (w http.ResponseWriter, r *http.Request)
a. (解析前)限制请求体大小
if r.ContentLength >= 0 && r.ContentLength > 1034*1024 {
// return errors.New("http: request body too large")
}
r.Body = http.MaxBytesReader(w, r.Body, 1034*1024)
如果请求体大小已知并且超长, 可以直接返错, 以避免上传1M+10K字节之后才报错而浪费流量.
b. 解析时限制上传文件占用的内存
r.ParseMultipartForm(50 * 1024) // e.g. 50K
超出时Go 会自动转存为磁盘临时文件.
c. 请求结束时清理临时文件
myhandler(w http.ResponseWriter, r *http.Request) {
defer func() {
if r.MultipartForm != nil {
r.MultipartForm.RemoveAll()
}
}()
...
}
3. 附录
读取上传文件
fh := r.MultipartForm.File["file1"] // multipart.FileHeader
f, _ := fh.Open() // multipart.File (注: 示例代码, 忽略了err)
defer f.Close()
f.Read(make([]byte, 1024))
...