使用React将表单发布到API

时间:2019-01-20 20:19:54

标签: reactjs post fetch-api gatsby

我在我的盖茨比(staticman.net)网站上使用静态人(gatsbyjs.org)发表评论。

我一直在使用带有method="POST"action="https://api.staticman.net/..."参数的经典HTML表单,因为这是Staticman期望的(docs)。

但是我想使它更“反应”,并且我将表单动作更改为handleSumbit()函数:

handleSubmit(event) {
  event.preventDefault()
  fetch("https://api.staticman.net/...", {
    method: "POST",
    body: event.target,
  })
}

我觉得这是行不通的,因为API期望HTTP POST request的内容类型为application/x-www-form-urlencoded,而我的event.target是带有React信息的表单。 / p>

如何使我的fetch()请求看起来完全像HTTP POST表单提交?

2 个答案:

答案 0 :(得分:1)

我会使用query-string包之类的组件从您的组件状态重建POST数据。不确定staticman的具体细节,但我认为您在react组件的状态下具有表单值,因此您可以执行以下操作:

handleSubmit = (event) => {
  event.preventDefault()
  fetch("https://api.staticman.net/...", {
    method: "POST",
    body: queryString.stringify({
      this.state.username,
      this.state.subject
    })
  })
}

答案 1 :(得分:0)

经过研究,我找到了 a 解决方案。这是我的handleSubmit函数:

handleSubmit = async (event) => {
  event.preventDefault()

  // extract form data
  const formdata = new FormData(event.target)

  // convert FormData to json object
  // SOURCE: https://stackoverflow.com/a/46774073
  const json = {}
  formdata.forEach(function(value, prop){
    json[prop] = value
  })

  // convert json to urlencoded query string
  // SOURCE: https://stackoverflow.com/a/37562814 (comments)
  const formBody = Object.keys(json).map(key => encodeURIComponent(key) + '=' + encodeURIComponent(json[key])).join('&')

  // POST the request to Staticman's API endpoint
  const response = await fetch("https://dev.staticman.net/v3/entry/github/robinmetral/eaudepoisson/master/comments", {
    method: "POST",
    headers: {"Content-Type": "application/x-www-form-urlencoded"},
    body: formBody,
  })
    .then(response => {
      // reset form
      document.getElementById("comment-form").reset()
      // display success message
      document.getElementById("success").style.display = "block"
    })
    .catch(error => {
      console.log(error)
      document.getElementById("failure").style.display = "block"
    })
}

这就是它的作用:

  1. 它将提取的数据提取为FormData对象
  2. 它使用snippet found on SO
  3. 将FormData转换为JSON对象
  4. 它使用another SO snippet将JSON转换为预期的application/x-www-form-urlencoded内容类型或“查询字符串”
  5. 它将请求发送到API端点,捕获错误并显示成功消息

这可能不是唯一的解决方案,如果您发现我可以改进的地方,请在评论或send me a PR中让我知道!