转到http服务器处理POST数据差异?

转到http服务器处理POST数据差异?,http,go,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="filepat

我有一个简单的上传表单

<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>
问题是当我使用
enctype=“multipart/form data”
时,我无法使用
r.PostFormValue
从客户端获取值,但如果我设置为
enctype=“application/x-www-form-urlencoded”
,则可以

PostFormValue返回POST的命名组件的第一个值 或者把请求放在正文中。URL查询参数被忽略。 PostFormValue在必要时调用ParseMultipartForm和ParseForm并忽略 这些函数返回的任何错误

那么,为什么他们没有在这里提到
enctype

如果您使用
多部分/表单数据“
表单数据编码类型,您必须使用函数读取表单值(请注意,不是
PostFormValue
!)

defaultHandler()
函数更改为:

func defaultHandler(w http.ResponseWriter, r *http.Request) {
    log.Println(r.FormValue("filepath"))
}
它会起作用的。这是因为
Request.FormValue()
Request.PostFormValue()
第一次调用
Request.ParseMultipartForm()
(如果表单编码类型为
multipart
且尚未解析)和
Request.ParseMultipartForm()
仅将解析后的表单名称-值对存储在
请求.form
中,而不存储在
请求.PostForm中:


这可能是一个错误,但即使这是预期的工作,也应该在文档中提及。

如果您试图上载文件,您需要使用
多部分/表单数据
enctype,输入字段必须是
type=file
,并使用
FormFile
而不是
PostFormValue
(仅返回字符串)方法


@secmask那么可能您没有在浏览器中重新加载HTML页面,或者您没有重新启动应用程序。这对我来说很有效。我已经尝试了这两种方法:(,我测试,转到1.3.3和1.4。1@secmask并将
r.PostFormValue()
更改为
r.FormValue()
FormValue
可以,但是为什么不
PostFormValue
?,从他们的文档中,我认为唯一的不同是
PostFormValue
在查询中不使用值url@secmask编辑了我的答案,解释了您在实现过程中的体验(源代码)我的表单没有文件,只有一些表单参数,但我更喜欢多部分而不是url编码表单。只是奇怪的是,go没有在这里统一使用(和文档)
func defaultHandler(w http.ResponseWriter, r *http.Request) {
    log.Println(r.FormValue("filepath"))
}
<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)
}