Reputation: 8107
I have a simple upload form as
<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>
And server side
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)
}
The problem is when I use enctype="multipart/form-data"
, I cannot get the value from client with r.PostFormValue
, but it's ok if I set to enctype="application/x-www-form-urlencoded"
, go document say
PostFormValue returns the first value for the named component of the POST or PUT request body. URL query parameters are ignored. PostFormValue calls ParseMultipartForm and ParseForm if necessary and ignores any errors returned by these functions.
So why they did not say anything about enctype
here ?
Upvotes: 1
Views: 1685
Reputation: 417592
If you use "multiplart/form-data"
form-data encoding type you have to read form values with the Request.FormValue()
function (note that not PostFormValue
!).
Change your defaultHandler()
function to:
func defaultHandler(w http.ResponseWriter, r *http.Request) {
log.Println(r.FormValue("filepath"))
}
And it will work. The reason for this is because both Request.FormValue()
and Request.PostFormValue()
first call Request.ParseMultipartForm()
if needed (if form encodying type is multipart
and it has not yet been parsed) and Request.ParseMultipartForm()
only stores the parsed form name-value pairs in the Request.Form
and not in Request.PostForm
: Request.ParseMultipartForm() source code
This may well be a bug, but even if this is the intended working, it should be mentioned in the documentation.
Upvotes: 1
Reputation: 698
If you are trying to upload files you need to use the multipart/form-data
enctype, the input field must be type=file
and use the FormFile
instead of PostFormValue
(that returns just a String) method.
<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)
}
Upvotes: 0