Пытаюсь остаться на странице после отправки: «Не удалось получить» (для написания формы использовался машинописный текст)

После попытки не перенаправить пользователя, отправившего форму, у меня возникли проблемы с отправкой формы в службу форм.

Я настраиваю форму Formspark для использования на сайтеframer.com. Framer.com заставляет меня использовать Typescript, о котором я не знаю (сейчас я знаю только HTML, CSS и JS). Я собрал идеи и случайную информацию из документации Formspark и сообщества Sitepoint. Я был бы очень (действительно) признателен, если бы кто-нибудь нашел немного свободного времени, чтобы помочь решить мою проблему.

Вот моя форма (упрощенная):

import React, { useEffect, useRef, useState } from "react"
import styled from "styled-components"

const SalesForm = styled.form`
  /*styles*/
`
const FormInput = styled.input`
  /*styles*/
`
const Button = styled.button`
  /*styles*/
`
const SuccessMessage = styled.div`
  /*styles*/
`
const ErrorMessage = styled.div`
  /*styles*/
`

export default function Form(props) {
    const captchaRef = useRef<HTMLDivElement>(null)
    const [token, setToken] = useState<string | null>(null)
    const [message, setMessage] = useState<string | null>(null)
    const [isSuccess, setIsSuccess] = useState<boolean | null>(null)

    useEffect(() => {
        console.info("Initializing hCaptcha...")
        if (window.hcaptcha) {
            window.hcaptcha.render(captchaRef.current!, {
                sitekey: "mycaptchacode",
                callback: (token: string) => {
                    console.info("hCaptcha token generated:", token)
                    setToken(token)
                },
            })
        }
    }, [])

    const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
        event.preventDefault()
        if (!token) {
            alert("Please verify that you are human.")
            return
        }

        const formData = new FormData(event.currentTarget)
        console.info("Form Data: ", Array.from(formData.entries()))

        try {
            const response = await fetch("https://submit-form.com/formid", {
                method: "POST",
                body: formData,
            })

            if (response.ok) {
                setMessage("Form successfully submitted!")
                setIsSuccess(true)
                event.currentTarget.reset()
            } else {
                const errorText = await response.text()
                console.error("Error response: ", errorText)
                setMessage(
                    "There was a problem with your submission: " + errorText
                )
                setIsSuccess(false)
            }
        } catch (error) {
            console.error("Submission error: ", error)
            setMessage(
                "There was an error submitting the form: " + error.message
            )
            setIsSuccess(false)
        }
    }

    return (
        <SalesForm id = "sales-form" onSubmit = {handleSubmit}>
            <script src = "https://js.hcaptcha.com/1/api.js" async defer></script>
            <FormInput type = "text" id = "comp-name" name = "comp-name" placeholder = "comp-name" required/>
            <div ref = {captchaRef}></div>
            <Button type = "submit">Send</Button>
            {message &&
                (isSuccess ? (
                    <SuccessMessage>{message}</SuccessMessage>
                ) : (
                    <ErrorMessage>{message}</ErrorMessage>
                ))}
        </SalesForm>
    )
}

Хочу дать немного больше информации:

  • handleSubmit работал, когда у него не было ничего, кроме первого оператора «if», который заставлял пользователя проверять капчу (следовательно, в моей форме были атрибуты метода и действия), у него также не было «асинхронного». Я добавил эти строки, чтобы они оставались на той же странице после отправки. Я просто использовал <input type = "hidden" name = "_redirect" value = "redirecturl.com" />. Не оставаться на той же странице было главным, что затащило меня сюда. Я не хочу, чтобы пользователь был перенаправлен.
  • Исходя из всего вышесказанного, я подозреваю, что проблема не в использовании капчи. И моя служба форм работала, пока я не попробовал не перенаправлять.
  • «Не удалось получить» — это ошибка, которая отображается под формой после того, как я попыталась ее отправить.

Я был бы очень признателен за вашу помощь.

Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Travel Booking Angular Template один из лучших Travel & Tour booking template in the world. 30+ валидированных HTML5 страниц, которые помогут...
1
0
86
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Насколько я могу судить, это должно работать, логика интерфейса кажется в порядке. Я думаю, вам нужно проверить URL-адрес, по которому вы публикуете. Несколько вещей, на которые стоит обратить внимание

Все, что вам нужно, чтобы предотвратить перенаправление, — это вызвать preventDefault при событии отправки. Итак, у вас есть event.preventDefault(), и это отлично работает.

В остальном мне не удалось повторить вашу ошибку, "Failed to fetch". Я сделал повтор с вашим кодом на https://replit.com/@maxmezzomo/Form-Submit. Я просто удалил ранний возврат и оповещение о капче, тоже не думаю, что в этом проблема.

Однако вы отправляете сообщение на https://submit-form.com/formid, который возвращает 404 с сообщением «Эта форма больше не существует». Даже из браузера вы получите то же самое, если щелкнете ссылку. Я бы сказал, что это ожидаемое поведение. Но это встроено в failed to fetch. Я просто думаю, что вам действительно нужен идентификатор, если вы хотите публиковать сообщения, например https://submit-form.com/<formid>, где formid — это место, где вы хотите публиковать сообщения.

Если у вас есть URL-адрес, указывающий на URL-адрес, ожидаемый сервером, вы сможете сделать свой запрос. Кажется, что в Formspark конечная точка ожидает следующие заголовки https://documentation.formspark.io/examples/ajax.html#axios-with-recaptcha-v2.

headers: {
  "Content-Type": "application/json",
  Accept: "application/json",
},

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

JSON.stringify(Object.fromEntries(Object.entries(formData)))

который должен предоставить json объекта с данными формы, то, что вам понадобится, зависит от того, чего ожидает API, но вы можете это изучить.

Обновил реплит этим, вроде работает, получаю 200.

Итак, теперь ответ имеет код 200, что означает, что данные формы были успешно отправлены. Но есть часть кода, которая все еще выдает ошибку, которая обнаруживается позже. Вы не можете использовать событие currentTarget после обработки события. Я не знаю, как именно оно работает, но, вероятно, поскольку оно асинхронно к моменту обработки события. ответ на запрос currentTarget имеет значение null. Поэтому простой способ — создать ссылку на цель, прежде чем делать запрос.

  const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
    const target = event.currentTarget;

    event.preventDefault()
    if (!token) {...

затем вы можете использовать эту переменную для вызова сброса.

Теперь пользовательский интерфейс также должен показывать, что форма успешно отправлена!

Эй, спасибо за ответ! Я использую там настоящий «формид». Используйте submit-form.com/aDAJt6OP . Если вы не используете hcaptcha, форма не будет отправлена.

Onur Özalp 29.05.2024 20:02

да, окей, круто, спасибо, с фактическим идентификатором возвращается 302. Итак, я вижу упомянутую вами ошибку. Глядя на документацию formpark, хотя ему нужны данные в формате json и с соответствующими заголовками json, я обновлю ответ, как только добавлю заголовки, я получу 200. Что касается капчи, по крайней мере, при повторении, я просто закомментировал эти строки, поэтому он отправляется

Max 29.05.2024 20:15

эй, чувак, спасибо тебе большое, что помог мне до сих пор. Вы можете очистить все строки, касающиеся капчи, и использовать «submit-form.com/DhrCyMyaP», потому что эта форма не требует капчи, я сделал ее в пробных целях.

Onur Özalp 29.05.2024 20:30

да, конечно, пожалуйста. Спасибо за создание новой формы, похоже, она работает, по крайней мере, в части http. Сейчас единственная проблема, которую я вижу, — это вызов сброса для currentTarget, который имеет значение null. Я обновлю ответ, чтобы объяснить это.

Max 29.05.2024 20:38

Эй, чувак, пользовательский интерфейс показывает, что форма отправлена. А также «ответ: Ответ {тип: 'cors', URL: 'submit-form.com/aDAJt6OP', перенаправлен: ложь, статус: 200, ок: правда,…}». НО теперь Formspark не получает форму. Дайте мне знать, если вы хотите узнать что-нибудь еще. Кстати, я еще раз протестировал форму, и форма все еще работает без кода, который удерживает пользователя на странице. Однако, чтобы не проявлять неуважения к вашим усилиям, большое вам спасибо. Я тоже все перепроверю.

Onur Özalp 29.05.2024 22:10

ЭВРИКА! Что я изменил: я добавил «const responseData = await response.json(); console.info({ResponseData });» эти строки дали мне данные ответа, а данные ответа были пустыми ( "{"responseData": {}}" ). Исправление: я создал новую константу, чтобы сделать formData простым объектом: formDataObject = Object.fromEntries(formData.entries()). Я установил formDataObject для преобразования в строку следующим образом: «body: JSON.stringify(formDataObject)». На этот раз моя форма была отправлена ​​в Formspark! Пожалуйста, отредактируйте свой ответ соответствующим образом, большое спасибо за вашу помощь.

Onur Özalp 30.05.2024 06:35

Приятно, приятно слышать, что это сработало!

Max 31.05.2024 16:18

Все проблемы были связаны с действием моей формы при отправке. По сути, основная проблема заключалась в том, что я не добавил правильные заголовки (Content-type и Accept) внутри «const response = ...», которые Formspark ожидал от моей формы, что немного смущает. Вторая проблема (с которой я не столкнулся, но в конечном итоге столкнулась с ней) заключается в том, что я не использовал formData как простой объект, а также не строкировал его. И последняя проблема заключалась в том, чтобы не использовать константное значение для сброса(), если ответ был в порядке, и если вы не используете константу для представления currentTarget, это приведет к ошибке.

Вот как это должно было выглядеть:

/* Other lines of code that have remained unchanged.*/

const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
        const target = event.currentTarget

        event.preventDefault()
        if (!token) {
            // You don't need to include this if you are not using captcha
            // alert("Please verify that you are human.")
            // return
        }

        const formData = new FormData(event.currentTarget)
        const formDataObject = Object.fromEntries(formData.entries())
        console.info("Form Data: ", formDataObject)

        try {
            const response = await fetch("https://submit-form.com/form-id", {
                method: "POST",
                headers: {
                    "Content-Type": "application/json",
                    Accept: "application/json",
                },
                body: JSON.stringify(formDataObject),
            })
            console.info({ response })
            const responseData = await response.json()
            console.info({ responseData })
            if (response.ok) {
                setMessage("Form successfully submitted!")
                setIsSuccess(true)
                target.reset()
            } else {
                const errorText = await response.text()
                console.error("Error response: ", errorText)
                setMessage(
                    "There was a problem with your submission: " + errorText
                )
                setIsSuccess(false)
            }
        } catch (error) {
            console.error("Submission error: ", error)
            setMessage(
                "There was an error submitting the form: " + error.message
            )
            setIsSuccess(false)
        }
    }
/* Other lines of code that have remained unchanged.*/

Большое спасибо Мистеру Максу

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