2016-12-17 3 views
1

Я использую fetch API, чтобы отправить два значения в мой POST обработчика запроса ...Анализировать req.body в запросе 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 
     }) 

Я хочу, чтобы сохранить как email и 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 Я получаю пустое место. Каков правильный способ его разбора?

ответ

3

Try с

type credentials struct { 
    Email string `json:"email"` 
    Password string `json:"password"` 
} 

Вы получаете в JSON с двумя значениями. Получающая структура должна иметь структуру, соответствующую вашему запросу. В противном случае, никакие заполнители не должны декодировать JSON, как в вашем случае - адрес электронной почты и пароль не имеют соответствующих структурных полей. Btw. если вы отправите "Test" в свой JSON, это сработает, так как у вас есть тестовое поле в вашей структуре!

Что касается названий полей. Если поля в JSON не начинаются с большой буквы или даже имеют разные имена, вы должны использовать так называемые теги. Дополнительная информация по тэгам: https://golang.org/pkg/encoding/json/#Marshal

В моем примере я использовал их, чтобы соответствовать имена полей структура ваших полей JSon, т.е. сделать email от матча JSon Email поле credentials структуры.

1

req.Body является io.Reader, и вы можете получить с помощью ioutil.ReadAll осушить его:

data, err := ioutil.ReadAll(req.Body) 
asString := string(data) // you can convert to a string with a typecast 

Но я не уверен, если это то, что вы имели в виду, пытаясь сохранить req.Body в виде строки.

Чтобы разобрать ответ в структуру данных, вы можете распаковать его в переменную типа *interface{}:

var creds interface{} 
decoder.Decode(&creds) 

А затем проверьте значение:

fmt.Printf("%#v\n", creds) 

Или, возможно, с помощью pp.Println(creds), который я найти легче читать.

Переменная creds будет представлять объект JSON, найденный в теле, для ввода вашего примера это будет map[string]interface{} с двумя записями, предположительно обе из них строки. Что-то вроде:

map[string]interface{}{ 
    "email": email_value, 
    "password": password_value, 
} 

и вы проверить значение:

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\n", email) 
} else { 
    // "email" property was a string (may be missing, may be something else) 
} 

documentation of json.Unmarshal объясняет семантику как произвольные JSON строк могут быть разобрана, не зная их структуры заранее в дискуссии о демаршаллизации интерфейса значения.

+0

Fwiw, другой ответ превосходен, я неправильно понял часть о том, что вы не уверены в структуре, в первоначальном вопросе четко указано, что код на стороне клиента находится под контролем автора. – nothingmuch

Смежные вопросы