如果请求通过值传递,则http请求值为空

Could someone explains what's happening here?

package main

import (
    "fmt"
    "net/http"
    "strings"
)

func Verify(req http.Request) string {
    return req.FormValue("g-recaptcha-response")
}

func main() {
    req, _ := http.NewRequest("POST", "http://www.google.com/search?q=foo&q=bar&both=x&prio=1&empty=not",
        strings.NewReader("z=post&both=y&prio=2&empty="))
    req.Header.Set("Content-Type", "application/x-www-form-urlencoded; param=value")
    Verify(*req)
    fmt.Println(req.FormValue("z"))
}

(https://play.golang.org/p/ve4Cc_JTzr)

This will produce an empty output. Now if I access the value "z" before passing the request as value, it works!

package main

import (
    "fmt"
    "net/http"
    "strings"
)

func Verify(req http.Request) string {
    return req.FormValue("g-recaptcha-response")
}

func main() {
    req, _ := http.NewRequest("POST", "http://www.google.com/search?q=foo&q=bar&both=x&prio=1&empty=not",
        strings.NewReader("z=post&both=y&prio=2&empty="))
    req.Header.Set("Content-Type", "application/x-www-form-urlencoded; param=value")
    Verify(*req)
    fmt.Println(req.FormValue("z"))
}

(https://play.golang.org/p/5ALnt-pHTl)

I have tried with several versions of go from 1.5 to 1.7, with the same odd result. If the request is passed by reference, it's working as expected.

It's because Request's body is io.Reader, and you can read from io.Reader only once, when you try to read content second time, there is no more data to read.

Method FormValue calls ParseForm, and it reads all data from the reader.