我正在使用fetch API 将两个值发送到我的 POST 请求处理程序:
fetch('http://localhost:8080/validation', {
method:'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
email:this.state.email,
password:this.state.password
})
我想在服务器端保存电子邮件和密码为字符串,以下是我的尝试:
type credentials struct {
Test string
}
func Validate(rw http.ResponseWriter, req *http.Request, _ httprouter.Params) {
decoder := json.NewDecoder(req.Body)
var creds credentials
err := decoder.Decode(&creds)
if err != nil {
panic(err)
}
fmt.Println(creds.Test)
}
问题是我不知道发送到 POST 结构的确切格式。我正在尝试将 req.Body 保存为字符串,但是没有得到任何结果。
当输入 fmt.Println 只得到一个空格,解析它的正确方法是什么?
Try with
type credentials struct {
Email string `json:"email"`
Password string `json:"password"`
}
You are receiving a JSON with two values. Receiving struct should have a structure matching your request. Otherwise, there are no placeholders to decode the JSON into, as in your case - email and password do not have matching struct fields. Btw. if you send "Test"
in your JSON, this would work, as you have a Test field in your struct!
Regarding field names. If fields in JSON do not start with a capital letter or even have different names, then you should use so called tags. More on tags: https://golang.org/pkg/encoding/json/#Marshal
In my example I used them to match struct field names to your json fields, i.e. to make email
from json match Email
field of the credentials
struct.
req.Body
is an io.Reader
, and you can get use ioutil.ReadAll
to drain it:
data, err := ioutil.ReadAll(req.Body)
asString := string(data) // you can convert to a string with a typecast
But I'm not sure if that's what you meant by trying to save req.Body
as a string.
To parse the response into a data structure, you can unmarshal it into a variable of type *interface{}
:
var creds interface{}
decoder.Decode(&creds)
And then examine the value:
fmt.Printf("%#v
", creds)
Or perhaps using pp.Println(creds)
which I find easier to read.
The creds
variable will represent the JSON object found in the body, for your example input this will be a map[string]interface{}
with two entries, presumably both of them strings. Something like:
map[string]interface{}{
"email": email_value,
"password": password_value,
}
and you check the values with:
email, ok := creds["email"].(string)
if ok {
// email will contain the value because creds["email"] passed the type check
fmt.Printf("submitted email is %#v
", email)
} else {
// "email" property was a string (may be missing, may be something else)
}
The documentation of json.Unmarshal
explains the semantics of how arbitrary JSON strings can be parsed without knowing their structure in advance in the discussion about unmarshalling to interface values.