Solicitud incorrecta 400 en admin-ajax.php de WordPress

23 sept 2021, 14:00:22
Vistas: 13.5K
Votos: 0

Intento ejecutar un formulario wp con ajax pero la consola devuelve 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("Hubo un error: " + err);
                    }
                });
                return false;
            });
        });
    });

aquí está mi archivo functions.php:

add_action('wp_ajax_send_form', 'send_form'); // Para usuarios autenticados
add_action('wp_ajax_nopriv_send_form', 'send_form'); // Para usuarios no autenticados

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

y mi formulario:

            <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="Añadir">

formulario completo: https://pastebin.com/YJXTjGjJ

FUNCIONANDO:

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("Hubo un error: " + err);
                    }
                });
                return false;
            });
        });
    });
2
Comentarios

"Tengo múltiples formularios para cada producto en mi página, pero el ajax solo funciona para el primer formulario" - has usado '#form_add_to_cart' como selector. Eso potencialmente solo selecciona un único elemento con id=form_add_to_cart: los IDs deberían ser únicos en la página.

Rup Rup
23 sept 2021 14:42:21

Ok, cambié el selector de ID a clase, ahora el clic funciona, pero sigue dando error 400

NCTI NCTI
23 sept 2021 14:44:16
Todas las respuestas a la pregunta 2
8

En la propiedad data necesitas pasar la acción a ser llamada junto con el resto de tus datos.
Basado en tu acción ajax, tu acción debería ser send_form

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

Ahora en tu función de callback php puedes hacer print_r($_POST) para ver qué contiene la petición POST.

23 sept 2021 14:30:20
Comentarios

Desafortunadamente el mismo error.

NCTI NCTI
23 sept 2021 14:35:22

@NCTI Después de la solicitud ajax, ¿puedes ir a network -> fetch/xhr -> encontrar la solicitud y revisar la respuesta, qué dice?

Buttered_Toast Buttered_Toast
23 sept 2021 14:37:36

Y tengo múltiples formularios para cada producto en mi página, pero ajax solo funciona para el primer formulario.

NCTI NCTI
23 sept 2021 14:39:20

Veo 0 en network -> fetch/xhr -> response

NCTI NCTI
23 sept 2021 14:41:01

@NCTI parece que tu URL es incorrecta, asegúrate de pasar la URL correcta. Si estás usando url: 'https://domain.com/wp-admin/admin-ajax.php' estoy 100% seguro que no funcionará, cámbiala por tu dominio

Buttered_Toast Buttered_Toast
23 sept 2021 14:44:52

Y tengo múltiples formularios para cada producto en mi página, pero ajax solo funciona para el primer formulario., el envío funciona para cada formulario con ese ID pero los datos que se pasan se toman del primer formulario con ese ID. En lugar de $("#form_add_to_cart").serialize(), haz $(this).serialize(),

Buttered_Toast Buttered_Toast
23 sept 2021 14:46:28

Continuemos esta discusión en el chat.

NCTI NCTI
23 sept 2021 15:29:36

cuando recibí datos en php intenté usar json_decode($data) y no me devolvió nada.

NCTI NCTI
23 sept 2021 16:03:50
Mostrar los 3 comentarios restantes
6

Tu código de formulario completo contiene un campo oculto llamado action con el valor send_form.

Sin embargo, no lo estás enviando correctamente debido a la parte de contentType en tu script JS, que envía los datos del formulario como una carga útil JSON. Ten en cuenta que el antiguo endpoint admin-ajax.php no admite cargas JSON, por lo que $_REQUEST['action'] estaría vacío a menos que lo agregues a la cadena de consulta de la URL. Por lo tanto, WordPress no sabrá cuál es la acción AJAX. Simplemente elimina lo siguiente de tu código JS y el error desaparecerá:

contentType : 'application/json; charset=utf-8', // elimina esto

Adicionalmente, tu formulario no tiene un campo llamado send_form, por lo que en tu función send_form(), esto fallará: if (isset($_POST['send_form'])). Deberías agregar el campo a tu formulario o cambiar la condición if.

También deberías llamar a wp_die() al final de tu función para salir de la página y evitar que WordPress imprima un 0 (cero).

23 sept 2021 14:46:56
Comentarios

Gracias, eso funciona. Ahora no puedo mostrar los datos pasados a mi función. Ejecuto send_form(); en la misma página cuando llamo a ajax, y no se muestra nada.

NCTI NCTI
23 sept 2021 15:17:08

Tu función, tal como está ahora, no muestra ninguno de los datos enviados, pero en realidad mostraría "ok" o "bad". Y para recuperar los datos enviados, simplemente usa el formato $_POST['nombre del input'], por ejemplo $_POST['quantity']. También, prueba con var_dump( $_POST ); al principio de la función y verás una lista de los datos del formulario enviados. Pero tu pregunta original ya ha sido respondida, así que si tienes otra pregunta, puedes hacerla en otra publicación. Sin embargo, ten en cuenta que las preguntas genéricas sobre PHP están fuera de tema en este stack y deberían hacerse en Stack Overflow.

Sally CJ Sally CJ
23 sept 2021 16:05:58

Además, por favor deshaz la edición de tu pregunta, es decir, vuelve a la versión anterior/original. Si querías agregar nuevo código, añádelo al final y no modifiques la parte que te dije que eliminaras :)

Sally CJ Sally CJ
23 sept 2021 16:09:05

Me devuelve datos como:

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 sept 2021 16:14:48

Ahora devuelve: 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 sept 2021 16:18:21

Vamos a continuar esta conversación en el chat.

Sally CJ Sally CJ
23 sept 2021 16:20:12
Mostrar los 1 comentarios restantes