我刚接触Golang,并想使用http
包创建API。因此,我尝试了以下代码段:
package main
import (
"fmt"
"net/http"
)
type server struct{}
func (s *server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
r.ParseForm()
fmt.Println(r.Header["Content-Type"][0])
fmt.Printf("The URL is: %s\n", r.Form)
}
func main() {
s := &server{}
http.Handle("/", s)
http.ListenAndServe(":8080", nil)
}
请求为:
curl localhost:8080 -d url=google.com -i
输出:
application/x-www-form-urlencoded
The URL is: map[url:[google.com]]
一切正常,直到使用自定义动词,如:
curl localhost:8080 -d url=google.com -i -X CREATE
输出:
application/x-www-form-urlencoded
The URL is: map[]
http
软件包和HTTP自定义动词有问题吗?
我的代码有问题吗?
答案 0 :(得分:3)
答案在ParseForm
的{{1}}来源中
net/http/request.go
仅当方法为POST,PUT或PATCH时,它才会解析POST正文。
您可以通过在致电 if r.Method == "POST" || r.Method == "PUT" || r.Method == "PATCH" {
r.PostForm, err = parsePostForm(r)
}
之前添加r.Method = "POST"
来强制执行此操作:
r.ParseForm
答案 1 :(得分:2)
https://golang.org/pkg/net/http/#Request
Form包含已解析的表单数据,包括URL字段的查询参数和PATCH,POST或PUT表单数据。 该字段仅在调用ParseForm之后可用。 HTTP客户端会忽略Form,而使用Body。
如果我们在ParseForm
中查看the code,则会看到:
if r.PostForm == nil {
if r.Method == "POST" || r.Method == "PUT" || r.Method == "PATCH" {
r.PostForm, err = parsePostForm(r)
}
if r.PostForm == nil {
r.PostForm = make(url.Values)
}
}
最简单的方法是让它认为这是一个POST请求(然后在以后重新设置它,以防以后需要真正的方法):
method := r.Method
r.PostForm == nil // this line may necessary
r.Method = http.MethodPost
r.ParseForm()
r.Method = method