我使用Go实现了一个PUT接口,在浏览器中可以使用ajax发送请求:
$.ajax({
url: "/api/accounts/" + email + "/", // Append back slash for put request
type: "PUT",
data: {"password": password, "name": name},
error: function(resp, status, error) {
let msg = resp.responseText;
if(status == 500) {
msg = "Internal error"
}
但是使用Go写test时,发送的请求却接收不到了:
values := url.Values {
"name": { "ethan" },
"password": { "password" },
}
req, err := http.NewRequest("PUT", urlPath, strings.NewReader(values.Encode()))
if err != nil {
t.Fatalf("%d: NewRequest failed with error: %s", i, err)
}
client := http.Client{}
resp, err := client.Do(req)
最终在request.go:ParseForm()函数中找到了答案:
FormValue可以处理url中的query键值对,对于PUT/POST/PATCH请求,也会将body中的内容处理成键值对,但Content-Type要设置成application/x-www-form-urlencoded,因此只要在request中添加这个header即可:
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
client := http.Client{}
resp, err := client.Do(req)
注释原文:
// ParseForm populates r.Form and r.PostForm.
//
// For all requests, ParseForm parses the raw query from the URL and updates
// r.Form.
//
// For POST, PUT, and PATCH requests, it also parses the request body as a form
// and puts the results into both r.PostForm and r.Form. Request body parameters
// take precedence over URL query string values in r.Form.
//
// For other HTTP methods, or when the Content-Type is not
// application/x-www-form-urlencoded, the request Body is not read, and
// r.PostForm is initialized to a non-nil, empty value.
//
// If the request Body's size has not already been limited by MaxBytesReader,
// the size is capped at 10MB.
//
// ParseMultipartForm calls ParseForm automatically.
// ParseForm is idempotent.