英文:
http request values are empty if the request is passed by value
问题
这段代码是一个使用Go语言编写的简单程序。它创建了一个HTTP请求,并尝试从请求中获取名为"g-recaptcha-response"的表单值。
在第一个示例中,程序创建了一个HTTP请求,并将其作为值传递给Verify函数。然后,它尝试从请求中获取名为"z"的表单值,并打印出来。但是,由于请求是通过值传递的,所以在Verify函数中对请求的修改不会影响到main函数中的请求对象,因此打印出的结果为空。
在第二个示例中,程序在调用Verify函数之前先获取了请求中的"z"值,并打印出来。然后,它将请求作为值传递给Verify函数,并再次尝试获取"z"的值。这次打印出的结果是正确的,因为在调用Verify函数之前已经获取了请求中的值。
总结起来,如果将请求作为值传递给函数,对请求的修改不会影响到原始的请求对象。如果想要在函数中修改请求对象并影响到原始的请求,可以将请求作为指针传递给函数。
这个问题在不同版本的Go语言中都存在,无论是1.5还是1.7版本。如果将请求作为指针传递给函数,它会按预期工作。
英文:
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.
答案1
得分: 5
这是因为请求的主体是io.Reader
,而你只能从io.Reader
中读取一次数据。当你尝试第二次读取内容时,就没有更多的数据可读取了。
FormValue
方法调用了ParseForm
,它会从读取器中读取所有的数据。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论