文件上传这类操作一般出现在的网站中,如:保存会员头像。这里我们以上传图片为例,来说明一个web页面如何上传文件至go语言web服务器。
完成文件上传,我们需要做以下两个操作,
第一步、创建upload.html,用户通过这个页面来选择并上传文件,源码如下
<html>
<head>
<title>Go语言上传文件</title>
</head>
<body>
<h1>Go语言上传文件</h1>
<form enctype="multipart/form-data" action="/upload" method="post">
<div><input type="file" name="uploadfile" /></div>
<div><input type="submit" value="上传" /></div>
<input type="hidden" name="token" value="{{.}}">
</form>
</body>
</html>
这里我们需要注意的是要想让表单可以上传文件,那么form中必须包含属性enctype="multipart/form-data"
第二步、定义web服务器端的处理过程upload,代码如下
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("0", h.Sum(nil))
t, _ := template.ParseFiles(".//html//template//upload.html")
t.Execute(w, token)
} else if r.Method == "POST" {
token := r.Form.Get("token")
//验证token的合法性
if token != "" {
tokenOK := false
for v := range queue {
if queue[v] == token {
tokenOK = true
break
}
}
if !tokenOK {
fmt.Fprintf(w, "页面异常")
return
}
} else {
//不存在token报错
fmt.Fprintf(w, "页面异常")
return
}
r.ParseMultipartForm(32 << 20) // 运算符<<是左移运算符,32 << 20表示32*(2的20次方)
file, handler, err := r.FormFile("uploadfile")
if err != nil {
fmt.Println(err)
return
}
defer file.Close()
fmt.Fprintf(w, "", handler.Header)
// 请在当前目录下创建uploadFile目录
f, err := os.OpenFile(".//uploadFile//"+handler.Filename, os.O_WRONLY|os.O_CREATE, 0666)
if err != nil {
fmt.Println(err)
return
}
defer f.Close()
io.Copy(f, file)
} else {
fmt.Fprintf(w, "it is not support.")
}
}
在main函数中增加路由绑定http.HandleFunc("/upload", upload)
这里需要说明的有两点,
1、服务器端处理上传的文件使用的是ParseMultipartForm,参数表示服务器分配的最大内存,当上传文件小于最大内存时上传文件被保存在服务内存中,如果超了则保存在临时文件。
2、另一个是获取上传文件句柄,是通过FormFile来实现的,接下来就可以使用Copy函数将文件写到服务器磁盘上了。
上传成功后服务器端返回上传请求头部,如图
原文地址:https://www.slvit.com/zdlDetail?id=75