Данные не передаются из HTML формы ejs в маршрут POST Express

Вопрос или проблема

Я работаю над проектом интернет-магазина, пытаюсь передать данные заказа со страницы корзины (шаблон ejs) в маршрут POST Express, но форма не определена, и переданные данные – это пустой объект.

cart.ejs:

<!DOCTYPE html>
<html lang="en">

<head>
    <%- include('partials/generic.ejs')%>
        <link rel="stylesheet" href="/css/cart.css">
</head>

<body>
    <% let totalprice=0; %>
        <%- include('partials/topNavBar.ejs')%>
            <% if(cartitems.length==0){ %>
                <% const title1="Ваша корзина пуста." %>
                    <% const title2="Посетите Apple Store" %>
                        <%- include('partials/alertScreen.ejs', {title1, title2}) %>
                            <% } %>

                                <% if(cartitems.length!=0){ %>
                                    <div id="main">

                                        <form action="/order" method="POST" id="entireForm">
                                            <section id="form1">
                                                <h1>Проверьте свою корзину.</h1>
                                                <% for(let item of cartitems){ %>
                                                    <% totalprice+=item.price %>
                                                        <div class="product_display">
                                                            <img src="<%= item.image_src %>" alt="" class="product_img">

                                                            <div class="product_details">
                                                                <span class="product_name">
                                                                    <%= item.displayName %>
                                                                </span>
                                                                <div class="additional_info">
                                                                    <% if(item.storageSize){ %>
                                                                        <span>
                                                                            <%= item.storageSize %>
                                                                        </span>
                                                                        <% } %>
                                                                            <% if(item.color){ %>
                                                                                <span>
                                                                                    <%= item.color %>
                                                                                </span>
                                                                                <% } %>
                                                                </div>
                                                            </div>
                                                            <span class="product_price">
                                                                <%= item.price+item.priceUnit %>
                                                            </span>
                                                            <form action="/cart/<%=item.id%>?_method=DELETE"
                                                                method="post">
                                                                <button class="deleteBtn" type="button">
                                                                    <img src="/pictures/cart/trashCan.png" alt="">
                                                                </button>
                                                            </form>
                                                        </div>
                                                        <hr>
                                                        <% }%>

                                                            <footer>
                                                                <div class="btnSection">
                                                                    <form action="/cart/all?_method=DELETE"
                                                                        method="post">
                                                                        <button class="formBtn1">Очистить корзину</button
                                                                            type="button">
                                                                    </form>
                                                                    <button class="formBtn2" type="button"
                                                                        id="form1next">Далее</button>
                                                                </div>
                                                                <span id="totalprice">
                                                                    <%= totalprice+"$" %>
                                                                </span>
                                                            </footer>
                                            </section>

                                            <section id="form2">
                                                <h1>Доставка.</h1>
                                                <div class="row">
                                                    <div class="form-group col-md-6">
                                                        <label for="firstName">Имя</label>
                                                        <input class="form-control" type="text" id="firstName"
                                                            placeholder="Введите ваше имя" name="firstName">
                                                    </div>
                                                    <div class="form-group col-md-6">
                                                        <label for="lastName">Фамилия</label>
                                                        <input class="form-control" type="text" id="lastName"
                                                            placeholder="Введите вашу фамилию" name="lastName">
                                                    </div>
                                                </div>

                                                <div class="form-group">
                                                    <label for="Adress">Адрес</label>
                                                    <input class="form-control" id="Adress" type="text"
                                                        placeholder="Адрес для доставки" name="Adress">
                                                </div>

                                                <div class="row">
                                                    <div class="form-group col-md-8">
                                                        <label for="email">Электронная почта</label>
                                                        <input class="form-control" type="email" id="email" name="email"
                                                            placeholder="example@mail.com">
                                                    </div>

                                                    <div class="form-group col-md-4">
                                                        <label for="phoneNumber">Номер телефона</label>
                                                        <input class="form-control" type="phoneNumber" id="phoneNumber"
                                                            name="phoneNumber" placeholder="050-0000-000">
                                                    </div>
                                                </div>

                                                <div class="form-group">
                                                    <label for="OrderNotes">Заметки о заказе</label>
                                                    <textarea class="form-control" name="OrderNotes" id="OrderNotes"
                                                        placeholder="Введите здесь..." rows="5" cols="30"></textarea>
                                                </div>

                                                <footer>
                                                    <div class="btnSection">
                                                        <button class="formBtn1" id="form2previous"
                                                            type="button">Назад</button>
                                                        <button class="formBtn2" id="form2next"
                                                            type="button">Далее</button>
                                                    </div>
                                                </footer>
                                            </section>
                                            <section id="paymentApproved">

                                                <h1>Оплата подтверждена!</h1>
                                                <input type="hidden" name="totalprice" value="<%= cartitems %>">
                                                <% for(let item of cartitems){ %>
                                                    <% totalprice+=item.price %>
                                                        <div class="product_display">
                                                            <img src="<%= item.image_src %>" alt="" class="product_img">

                                                            <div class="product_details">
                                                                <span class="product_name">
                                                                    <%= item.displayName %>
                                                                </span>
                                                                <div class="additional_info">
                                                                    <% if(item.storageSize){ %>
                                                                        <span>
                                                                            <%= item.storageSize %>
                                                                        </span>
                                                                        <% } %>
                                                                            <% if(item.color){ %>
                                                                                <span>
                                                                                    <%= item.color %>
                                                                                </span>
                                                                                <% } %>
                                                                </div>
                                                            </div>
                                                            <span class="product_price">
                                                                <%= item.price+item.priceUnit %>
                                                            </span>
                                                        </div>
                                                        <hr>
                                                        <% } %>

                                                            <% } %>
                                                                <footer>
                                                                    <div class="btnSection">
                                                                        <button class="formBtn1" type="button"
                                                                            id="cancelOrderBtn">Отмена
                                                                            заказа</button>
                                                                        <button class="formBtn2"
                                                                            id="submitOrderBtn">Подтвердить
                                                                            заказ</button>
                                                                    </div>
                                                                    <span id="totalprice">
                                                                        <%= totalprice+"$" %>
                                                                    </span>
                                                                </footer>

                                            </section>
                                        </form>

                                        <section id="form3">

                                            <h1>Время платить.</h1>

                                            <form action="/payment" method="POST" id="paymentForm">

                                                <div class="form-group">
                                                    <label for="CreditCardNumber">Номер кредитной карты</label>
                                                    <input class="form-control" id="CreditCardNumber" type="text"
                                                        placeholder="***************" name="CreditCardNumber" required>
                                                </div>

                                                <div class="row">
                                                    <div class="form-group col">
                                                        <label for="date">Срок действия</label>
                                                        <input class="form-control" id="date" type="text"
                                                            placeholder="MM-YYYY" name="date" required>
                                                    </div>
                                                    <div class="form-group col">
                                                        <label for="CVV">Код безопасности карты</label>
                                                        <input class="form-control" id="CVV" type="text"
                                                            placeholder="CVV" name="CVV" required>
                                                    </div>
                                                    <input type="hidden" name="totalprice" value="<%= totalprice %>">
                                                </div>

                                                <footer>
                                                    <div class="btnSection">
                                                        <button class="formBtn1" type="button"
                                                            id="form3previous">Назад</button>
                                                        <button class="formBtn2" type="submit">Оплатить</button>
                                                    </div>
                                                    <span id="totalprice">
                                                        <%= totalprice+"$" %>
                                                    </span>
                                                </footer>

                                            </form>

                                        </section>

                                        <section id="paymentFailed">
                                            <% const title1="Извините, не удалось обработать платеж" %>
                                                <%- include('partials/alertScreen.ejs', {title1, title2:""}) %>
                                        </section>

                                    </div>

                                    <%- include('partials/buttomNavBar.ejs')%>
                                        <script src="/js/cart/cart.js"></script>
</body>

</html>

cart.js:

const mainForm = document.getElementById('entireForm');
console.log(mainForm)

document.addEventListener('DOMContentLoaded', () => {

    const form1nextbtn = document.querySelector("#form1next");
    const form2nextbtn = document.querySelector("#form2next");

    const form2previousbtn = document.querySelector('#form2previous');
    const form3previousbtn = document.querySelector('#form3previous');

    const form1 = document.querySelector('#form1');
    const form2 = document.querySelector('#form2');
    const form3 = document.querySelector('#form3');

    form2.style.display = "none";
    form3.style.display = "none";

    form1nextbtn.addEventListener('click', () => {
        form1.style.display = "none";
        form3.style.display = "none";

        form2.style.display = "block";
        form2.style.visibility = "visible";
    })

    form2nextbtn.addEventListener('click', () => {
        form1.style.display = "none";
        form2.style.display = "none";

        form3.style.display = "block";
        form3.style.visibility = "visible";
    })

    form2previousbtn.addEventListener('click', () => {
        form3.style.display = "none";
        form2.style.display = "none";

        form1.style.display = "block";
        form1.style.visibility = "visible";
    })
    form3previousbtn.addEventListener('click', () => {
        form3.style.display = "none";
        form1.style.display = "none";

        form2.style.display = "block";
        form2.style.visibility = "visible";
    })

    const paymentApproved = document.querySelector('#paymentApproved');
    paymentApproved.style.display = "none";
    const paymentFailed = document.querySelector('#paymentFailed');
    paymentFailed.style.display = "none";

    const paymentForm = document.querySelector('#paymentForm');

    paymentForm.addEventListener('submit', async (event) => {
        event.preventDefault();

        const formData = new FormData(paymentForm);
        const data = Object.fromEntries(formData.entries());

        try {

            const response = await fetch('/payment', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(data)
            });

            const result = await response.json();

            form3.style.display = "none";

            if (result.paymentSuccess) {
                paymentApproved.style.display = "block";
                console.log("Форма будет отправлена дальше");
                mainForm.submit();
            }
            else {
                paymentFailed.style.display = "block";
                paymentFailed.style.visibility = "visible";

            }
        } catch (error) {
            console.error('Ошибка:', error);
        }
    });
});

маршруты express в index.js:

const express = require("express");
const app = express();
const morgan = require("morgan");

app.use(express.json());
app.post('/payment', (req, res) => {
    //имитация проверки платежа
    console.log(req.body)
    const rand = Math.floor(Math.random() * (10) + 1)
    if (rand > 2) { res.json({ paymentSuccess: true }); }
    else { res.json({ paymentSuccess: false }); }
})

app.use(express.urlencoded({ extended: true }));
app.post('/order', (req, res) => {

    console.log(JSON.stringify(req.body));
    console.log(req.body);

    res.send("в маршруте POST order: форма отправлена")
})

app.listen('300', () => {
    console.log("слушаем на порту 300");
})

вывод в терминале:

GET /cart 304 – – 10.305 ms

{ CreditCardNumber: ‘r’, date: ‘r’, CVV: ‘r’, totalprice: ‘2496’ }

POST /payment 200 23 – 18.496 ms

{}

{}

POST /order 200 35 – 1.941 ms

Я пробовал всё, и ничто не работает.

Ответ или решение

Проблема, которую вы описали, заключается в том, что данные формы не передаются правильно на ваш маршрут Express после отправки формы. Ваша конфигурация выглядит довольно хорошо, и, следуя предоставленной информации, есть несколько моментов, на которые стоит обратить внимание.

1. Проверка структуры форм

На первой странице вашего вопроса вы указали HTML-шаблон с формами. Важно убедиться, что все поля формы имеют правильные атрибуты name, так как именно они используются для идентификации данных на сервере. Проверьте, что каждый элемент input и textarea имеют корректные атрибуты name.

Пример правильной настройки:

<input class="form-control" type="text" name="firstName" ...>
<textarea class="form-control" name="OrderNotes" ...></textarea>

2. Сбор данных формы

Ваш код JavaScript в cart.js предотвращает стандартное поведение отправки формы, чтобы выполнить проверку платежа. Однако, ввиду того, что вы используете event.preventDefault(), необходимо убедиться, что данные формы действительно передаются на сервер после успешной проверки.

Ваша логика в paymentForm.addEventListener('submit'...) может быть причиной не получения данных на сервере. Вы должны вызвать mainForm.submit(); после того, как проверка успешного платежа завершена, а также подождать, пока ответ от вашего сервера будет обработан.

Вот улучшенный пример:

paymentForm.addEventListener('submit', async (event) => {
    event.preventDefault();

    const formData = new FormData(paymentForm);
    const data = Object.fromEntries(formData.entries());

    try {
        const response = await fetch('/payment', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(data)
        });

        const result = await response.json();

        if (result.paymentSuccess) {
            paymentApproved.style.display = "block";
            mainForm.submit(); // Здесь вы отправляете основную форму после успешного платежа.
        } else {
            paymentFailed.style.display = "block";
        }
    } catch (error) {
        console.error('Ошибка:', error);
    }
});

3. Убедитесь, что данные правильно обрабатываются на сервере

На вашей стороне Express вы правильно обрабатываете формы с помощью express.urlencoded({ extended: true }). Однако, убедитесь, что этот middleware вызывается до ваших маршрутов.

Вот правильный порядок:

app.use(express.urlencoded({ extended: true }));
app.use(express.json());

app.post('/payment', (req, res) => {
    console.log(req.body);
    // Ваша логика проверки платежа
});

app.post('/order', (req, res) => {
    console.log(req.body);
    res.send("В маршруте пост-ордера: форма отправлена");
});

4. Проверка отсутствующих данных

Если после всех изменений данные все еще приходят пустыми, попробуйте проверить:

  • Названия переменных в input полях, чтобы они соответствовали тому, что вы ожидаете на стороне сервера.
  • Откройте вкладку "Сеть" в инструментах разработчика вашего браузера и посмотрите на запрос POST /order. Проверьте в разделе "Payload" (или "Тело запроса"), какие данные действительно отправляются.

Заключение

Используя вышеперечисленные рекомендации, вы должны быть в состоянии отладить и исправить вашу проблему с отправкой данных формы из шаблона EJS в маршруты Express. Если у вас остались вопросы или возникли новые проблемы, не стесняйтесь уточнять!

Оцените материал
Добавить комментарий

Капча загружается...