POST 使用 React 的 API 表单

POST a form to an API with React

我使用 Staticman (staticman.net) for comments on my Gatsby (gatsbyjs.org) 网站。

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

但是我想把它做得更多 "React",并且我已经将表单操作更改为 handleSumbit() 函数:

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

我觉得这行不通,因为 API 需要 和 application/x-www-form-urlencoded 内容类型,而我的 event.target 是一种形式大量 React 信息。

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

我会使用 query-string 包之类的东西从您的组件状态重建 POST 数据。不确定 staticman 的具体细节,但我假设你的反应组件状态中有表单值,所以你可以做类似的事情:

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

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

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

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

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

  // convert json to urlencoded query string
  // SOURCE:  (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. 它使用
  3. 将 FormData 转换为 JSON 对象
  4. 它使用
  5. 将 JSON 转换为预期的 application/x-www-form-urlencoded 内容类型或 "query string"
  6. 它将请求发送到 API 端点,捕获错误并显示成功消息

这可能不是唯一的解决方案,如果您看到我可以改进的地方,请在评论中告诉我或 send me a PR!