POST форма в API с React

Я использую Staticman (staticman.net) для комментариев на моем сайте Gatsby (gatsbyjs.org).

Я использовал классическую HTML-форму с параметрами method = "POST" и action = "https://api.staticman.net/...", поскольку именно этого ожидает Staticman (документы).

Однако я хотел бы сделать это более «реагирующим», и я изменил действие формы на функцию handleSumbit():

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

Я чувствую, что это не работает, потому что API ожидает POST-запрос HTTP с типом контента application/x-www-form-urlencoded, тогда как мой event.target — это форма с большим количеством информации React.

Как я могу сделать так, чтобы мой запрос fetch() выглядел точно так же, как отправка формы HTTP POST?

Сопровождающий Staticman рекомендует пользователям запускать собственный экземпляр API в github.com/eduardoboucas/staticman/issues/….

GNUSupporter 8964民主女神 地下教會 01.02.2021 14:55
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
3
1
7 240
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я бы восстановил эти данные POST из состояния вашего компонента, используя что-то вроде пакета query-string. Не уверен в специфике staticman, но я предполагаю, что у вас есть значения формы в состоянии вашего реагирующего компонента, поэтому вы можете сделать что-то вроде:

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

Спасибо за совет по строкам запроса! В итоге я нашел способ конвертировать FormData в строку запроса вручную (через JSON). Не идеально, но работает :)

Robin Métral 21.01.2019 15:59
Ответ принят как подходящий

После некоторых исследований я нашел решение а. Вот моя функция 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.info(error)
      document.getElementById("failure").style.display = "block"
    })
}

Вот что он делает:

  1. он извлекает отправленные данные как объект Данные формы
  2. он преобразует FormData в объект JSON, используя фрагмент найден на SO
  3. он преобразует JSON в ожидаемый тип контента application/x-www-form-urlencoded или «строку запроса», используя другой фрагмент SO
  4. он отправляет запрос в конечную точку API, перехватывает ошибки и отображает сообщение об успешном выполнении

Возможно, это не единственное решение, и если вы видите что-то, что я мог бы улучшить, сообщите мне об этом в комментариях или пришлите мне пиар!

Другие вопросы по теме