去http服务器处理POST数据的区别?

时间:2015-01-20 10:17:04

标签: http go

我有一个简单的上传表单

<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呢?

2 个答案:

答案 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.FormRequest.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)
}