我有一个简单的上传表单
<html>
<title>Go upload</title>
<body>
<form action="http://localhost:8899/up" method="post" enctype="multipart/form-data">
<label for="file">File Path:</label>
<input type="text" name="filepath" id="filepath">
<p>
<label for="file">Content:</label>
<textarea name="jscontent" id="jscontent" style="width:500px;height:100px" rows="10" cols="80"></textarea>
<p>
<input type="submit" name="submit" value="Submit">
</form>
</body>
</html>
和服务器端
package main
import (
"net/http"
"log"
)
func defaultHandler(w http.ResponseWriter, r *http.Request) {
log.Println(r.PostFormValue("filepath"))
}
func main() {
http.HandleFunc("/up", defaultHandler)
http.ListenAndServe(":8899", nil)
}
问题是,当我使用enctype="multipart/form-data"
时,我无法通过r.PostFormValue
从客户端获取值,但是如果我设置为enctype="application/x-www-form-urlencoded"
就可以了,请说文档
PostFormValue返回POST命名组件的第一个值 或PUT请求正文。 URL查询参数将被忽略。 如果需要,PostFormValue会调用ParseMultipartForm和ParseForm并忽略 这些函数返回的任何错误。
那么为什么他们在这里没有说enctype
呢?
答案 0 :(得分:1)
如果您使用"multiplart/form-data"
表单数据编码类型,则必须使用Request.FormValue()
函数读取表单值(请注意,不是PostFormValue
!)。
将defaultHandler()
功能更改为:
func defaultHandler(w http.ResponseWriter, r *http.Request) {
log.Println(r.FormValue("filepath"))
}
它会起作用。这是因为Request.FormValue()
和Request.PostFormValue()
如果需要,首先调用Request.ParseMultipartForm()
(如果表单编码类型为multipart
并且尚未解析){{1只存储已解析的表单名称 - 值对Request.ParseMultipartForm()
而不是Request.Form
:Request.ParseMultipartForm() source code
这可能是一个错误,但即使这是预期的工作,也应该在文档中提及。
答案 1 :(得分:0)
如果您尝试上传文件,则需要使用multipart/form-data
enctype,输入字段必须为type=file
,并使用FormFile
代替PostFormValue
(返回只是一个String)方法。
<html>
<title>Go upload</title>
<body>
<form action="http://localhost:8899/up" method="post" enctype="multipart/form-data">
<label for="filepath">File Path:</label>
<input type="file" name="filepath" id="filepath">
<p>
<label for="jscontent">Content:</label>
<textarea name="jscontent" id="jscontent" style="width:500px;height:100px" rows="10" cols="80"></textarea>
<p>
<input type="submit" name="submit" value="Submit">
</form>
</body>
</html>
package main
import (
"log"
"net/http"
)
func defaultHandler(w http.ResponseWriter, r *http.Request) {
file, header, err := r.FormFile("filepath")
defer file.Close()
if err != nil {
log.Println(err.Error())
}
log.Println(header.Filename)
// Copy file to a folder or something
}
func main() {
http.HandleFunc("/up", defaultHandler)
http.ListenAndServe(":8899", nil)
}