WordPress admin-ajax.php 400 bad request - решение проблемы

23 сент. 2021 г., 14:00:22
Просмотры: 13.5K
Голосов: 0

Пытаюсь отправить форму через AJAX в WordPress, но консоль возвращает ошибку: Wordpress admin-ajax.php 400 bad request.

jQuery(function ($) {
        $(document).ready(function () {
    
            jQuery('#form_add_to_cart').on('submit', function () {
                
                jQuery.ajax({
                    url: 'https://domain.com/wp-admin/admin-ajax.php', 
                    method: 'post',
                    contentType : 'application/json; charset=utf-8',
                    data: $("#form_add_to_cart").serializeArray(),
                    success: function (response) {
                        alert(response);
                    },
                    fail: function (err) {
                        alert("Произошла ошибка: " + err);
                    }
                });
                return false;
            });
        });
    });

Вот мой файл functions.php:

add_action('wp_ajax_send_form', 'send_form'); // Для авторизованных пользователей
add_action('wp_ajax_nopriv_send_form', 'send_form'); // Для неавторизованных пользователей

function send_form(){
    if (isset($_POST['send_form'])){
        echo'ok';
    }
    else{
        echo 'bad';
    }
}

И моя форма:

            <form name="form_add_to_cart" method="POST" class="form_product" id="form_add_to_cart" action="">

                        <input hidden="hidden" name="action" id="add_product_to_cart"
                               value="send_form">
                        <input class="btn btn-primary" type="submit"
                               name="add_to_cart-<?php echo $product_id; ?>" id="add_to_cart"
                               value="Добавить">

Полная форма: https://pastebin.com/YJXTjGjJ

РАБОЧЕЕ РЕШЕНИЕ:

jQuery(function ($) {
        $(document).ready(function () {


            jQuery('#form_add_to_cart').on('submit', function () {

                jQuery.ajax({
                    url: 'https://domain.com/wp-admin/admin-ajax.php', 
                    method: 'post',
                    data: $("#form_add_to_cart").serializeArray(),
                    success: function (response) {
                        alert(response);
                    },
                    fail: function (err) {
                        alert("Произошла ошибка: " + err);
                    }
                });
                return false;
            });
        });
    });
2
Комментарии

"У меня на странице несколько форм для каждого товара, но ajax работает только для первой формы" - вы использовали '#form_add_to_cart' как селектор. Это потенциально выбирает только один элемент с id=form_add_to_cart: идентификаторы должны быть уникальными на странице.

Rup Rup
23 сент. 2021 г. 14:42:21

Хорошо, я изменил селектор с ID на класс, теперь клик работает, но все равно получаю ошибку 400

NCTI NCTI
23 сент. 2021 г. 14:44:16
Все ответы на вопрос 2
8

В свойстве data необходимо передать действие, которое будет вызвано вместе с остальными данными.
В зависимости от вашего ajax-действия, действие должно быть send_form

data: {
    action: 'send_form',
    formData: $("#form_add_to_cart").serialize()
}

Теперь в вашей php-функции обратного вызова вы можете использовать print_r($_POST), чтобы увидеть содержимое POST-запроса.

23 сент. 2021 г. 14:30:20
Комментарии

К сожалению, та же самая ошибка.

NCTI NCTI
23 сент. 2021 г. 14:35:22

@NCTI После ajax-запроса, можешь зайти в Network -> Fetch/XHR -> найти запрос и проверить ответ, что там написано?

Buttered_Toast Buttered_Toast
23 сент. 2021 г. 14:37:36

И у меня несколько форм для каждого товара на странице, но ajax работает только для первой формы.

NCTI NCTI
23 сент. 2021 г. 14:39:20

Я вижу 0 в network -> fetch/xhr -> response

NCTI NCTI
23 сент. 2021 г. 14:41:01

@NCTI похоже, ваш URL указан неверно, убедитесь, что передаете правильный URL. Если вы используете url: 'https://domain.com/wp-admin/admin-ajax.php', я на 100% уверен, что это не сработает - измените на ваш домен

Buttered_Toast Buttered_Toast
23 сент. 2021 г. 14:44:52

У меня несколько форм для каждого товара на странице, но ajax работает только для первой формы. Отправка работает для каждой формы с этим id, но данные берутся из первой формы с таким id. Вместо $("#form_add_to_cart").serialize(), используйте $(this).serialize(),

Buttered_Toast Buttered_Toast
23 сент. 2021 г. 14:46:28

Давайте продолжим это обсуждение в чате.

NCTI NCTI
23 сент. 2021 г. 15:29:36

когда я получил данные в PHP, попытался использовать json_decode($data), и он ничего не вернул.

NCTI NCTI
23 сент. 2021 г. 16:03:50
Показать остальные 3 комментариев
6

Ваш полный код формы действительно содержит скрытое поле ввода с именем action и значением send_form.

Однако вы отправляете его некорректно из-за параметра contentType в вашем JS-скрипте, который отправляет данные формы в виде JSON-пакета. Учтите, что старый эндпоинт admin-ajax.php не поддерживает JSON-пакеты, поэтому $_REQUEST['action'] будет пустым, если вы не добавили его в строку запроса URL. В результате WordPress не сможет определить, какое AJAX-действие выполняется. Просто удалите следующую строку из вашего JS-кода, и ошибка исчезнет:

contentType : 'application/json; charset=utf-8', // удалите эту строку

Кроме того, в вашей форме нет поля ввода с именем send_form, поэтому в вашей функции send_form() условие if (isset($_POST['send_form'])) не сработает. Вам следует добавить это поле в форму или изменить условие if.

Также в конце функции следует вызвать wp_die(), чтобы завершить выполнение страницы и предотвратить вывод WordPress нуля (0).

23 сент. 2021 г. 14:46:56
Комментарии

Спасибо, это работает. Теперь я не могу отобразить переданные данные в моей функции. Я вызываю send_form(); на той же странице, когда выполняю ajax-запрос, но ничего не отображается.

NCTI NCTI
23 сент. 2021 г. 15:17:08

Ваша функция в текущем виде не выводит никаких отправленных данных, но она должна отображать либо "ok", либо "bad". Чтобы получить отправленные данные, используйте формат $_POST['имя поля'], например, $_POST['quantity']. Также попробуйте добавить var_dump( $_POST ); в начале функции, и вы увидите список отправленных данных формы. Однако ваш первоначальный вопрос уже был решён, поэтому, если у вас есть другой вопрос, задайте его в новом посте. Учтите, что общие вопросы по PHP не относятся к тематике этого стека и их следует задавать на Stack Overflow.

Sally CJ Sally CJ
23 сент. 2021 г. 16:05:58

Также, пожалуйста, отмените правку вашего вопроса, то есть вернитесь к предыдущей/оригинальной версии. Если вы хотели добавить новый код, поместите его в конце, а не изменяйте ту часть, которую я просил удалить :)

Sally CJ Sally CJ
23 сент. 2021 г. 16:09:05

Мне возвращаются данные в виде:

array(2) { ["action"]=> string(9) "send_form" ["formData"]=> array(9) { [0]=> array(2) { ["name"]=> string(8) "quantity" ["value"]=> string(1) "1" } [1]=> array(2) { ["name"]=> string(7) "do_wash" ["value"]=> string(2) "on" } [2]=> array(2) { ["name"]=> string(10) "product_id" ["value"]=> string(2) "12" } [3]=> array(2) { ["name"]=> string(13) "product_price" ["value"]=> string(3) "0.5" } [4]=> array(2) { ["name"]=> string(26) "product_person_to_bringing" ["value"]=> string(1) "0" } [5]=> array(2) } } }

NCTI NCTI
23 сент. 2021 г. 16:14:48

Теперь возвращается: array(2) { ["action"]=> string(9) "send_form" ["formData"]=> string(178) "quantity=1&do_wash=on&product_id=12&product_price=0.5&product_person_to_bringing=0&product_wash_price=0.2&product_bringing_price=0.4&product_calculate_bringing=0&action=send_form" } id_produktu0

NCTI NCTI
23 сент. 2021 г. 16:18:21

Давайте продолжим обсуждение в чате.

Sally CJ Sally CJ
23 сент. 2021 г. 16:20:12
Показать остальные 1 комментариев