Error 400 bad request en admin-ajax.php usando solo el hook de acción wp_enqueue_scripts

17 ene 2018, 12:39:08
Vistas: 108K
Votos: 24

He estado trabajando con ajax últimamente. Los tutoriales que encuentras en internet son todos muy similares y bastante fáciles de implementar. Pero siempre obtengo un bad request 400 en mi archivo ajax-admin.php.

Después de una larga e intensiva búsqueda, he descubierto que es debido al momento de la integración.

Si uso el hook de acción init para inicializar el script y wp_localize_script, todo funciona bien. Por lo que el código en sí debe ser correcto.

my-page-test-functions.php

function ajax_login_init(){
   wp_register_script('ajax-login-script',get_stylesheet_directory_uri().'/js/ajax-login-script.js',array('jquery'));
   wp_enqueue_script('ajax-login-script');
   wp_localize_script('ajax-login-script','ajax_login_object',array('ajaxurl' => admin_url('admin-ajax.php'),'redirecturl' => 'URL_DE_REDIRECCION_AQUI','loadingmessage' => __('Enviando información del usuario, por favor espere...')));
   add_action('wp_ajax_nopriv_ajaxlogin','ajax_login');
}

if(!is_user_logged_in()){
   add_action('init','ajax_login_init');
}

function ajax_login(){
    // el campo nonce se crea en la página
    check_ajax_referer('ajax-login-nonce','security');
    //CÓDIGO
    die();
}

Pero si uso por ejemplo el hook de acción wp_enqeue_scripts siempre obtengo el bad request.

if(!is_user_logged_in()){
    add_action('wp_enqueue_scripts','ajax_login_init');
}

El problema con esto es:

Me gustaría tener las funciones en un archivo php extra y cargarlas solo si son necesarias en una página en particular. Para esto necesito, por ejemplo is_page(). Pero is_page() funciona como muy pronto cuando engancho la función con el include en el hook de acción parse_query:

functions.php

function sw18_page_specific_functions(){
    if(is_page('page-test')){
        include_once dirname(__FILE__).'/includes/my-page-test-functions.php';
    }
}

add_action('parse_query','sw18_page_specific_functions');

Entonces las funciones enganchadas al hook init en el archivo my-page-test-functions.php no se disparan, supongo, porque init viene antes que parse_query.

¿Existe alguna mejor práctica para organizar esto, de manera que funcione? ¿O cómo puedo arreglar el bad request de admin-ajax.php cuando uso el hook de acción wp_enqeue_scripts?

1
Comentarios

puedes revisar esta discusión aquí https://stackoverflow.com/a/66464509/13278193

mod7ex mod7ex
3 mar 2021 22:44:13
Todas las respuestas a la pregunta 4
4
21

Creo que lo único que falta aquí es que necesitas mover add_action('wp_ajax_nopriv_ajaxlogin','ajax_login'); fuera de ajax_login_init.

Ese código registra tu manejador de Ajax, pero cuando solo lo ejecutas en wp_enqueue_scripts, ya es demasiado tarde y los hooks de wp_ajax_nopriv_ ya se han ejecutado.

Entonces, ¿has probado algo como esto?

function ajax_login_init(){
  if ( ! is_user_logged_in() || ! is_page( 'page-test' ) ) {
    return;
  }

  wp_register_script('ajax-login-script',get_stylesheet_directory_uri().'/js/ajax-login-script.js',array('jquery'));
  wp_enqueue_script('ajax-login-script');
  wp_localize_script('ajax-login-script','ajax_login_object',array('ajaxurl' => admin_url('admin-ajax.php'),'redirecturl' => 'URL_DE_REDIRECCIÓN_AQUÍ','loadingmessage' => __('Enviando información del usuario, por favor espere...')));
}

add_action( 'wp_enqueue_scripts','ajax_login_init' );

add_action( 'wp_ajax_nopriv_ajaxlogin','ajax_login' );

function ajax_login(){
  //nonce-field se crea en la página
  check_ajax_referer('ajax-login-nonce','security');
  //CÓDIGO
  die();
}

Edición:

Ahora está más claro que solo quieres cargar el JavaScript en esa página en particular. Esto significa que necesitas poner tu is_page() dentro de ajax_login_init(). He actualizado el código en consecuencia.

Ahora, ¿por qué no funcionó tu solución?

La verificación is_page() significaba que tu archivo de funciones solo se cargaba en esa página específica. ajax_login_init() se llama y tus scripts se encolan. Hasta aquí todo bien.

Ahora tu script hace la llamada ajax. Como se mencionó en los comentarios, las llamadas ajax no son conscientes de la página actual en la que te encuentras. Hay una razón por la que el archivo está en wp-admin/admin-ajax.php. No hay WP_Query y por lo tanto is_page() no funciona durante una solicitud ajax.

Como eso no funciona, sw18_page_specific_functions() no hará nada en un contexto ajax. Esto significa que tu archivo de funciones no se carga y tu manejador ajax no existe.

Por eso necesitas incluir siempre ese archivo de funciones y mover esa verificación is_page() dentro de ajax_login_init().

Así que en lugar de sw18_page_specific_functions() { … } simplemente ejecuta include_once dirname(__FILE__).'/includes/my-page-test-functions.php'; directamente. Sin ninguna llamada a add_action( 'parse_query' ).

17 ene 2018 12:48:26
Comentarios

Buena sugerencia. He cambiado eso (aún el mismo error), pero el problema sigue siendo que el archivo que contiene las funciones se cargará demasiado tarde. Pero necesito una forma de distinguir qué página se está utilizando. - actualmente intento esto con is_page() como se describió anteriormente.

Sin Sin
17 ene 2018 13:04:22

¿Estás intentando ejecutar is_page() desde dentro de ajax_login() o desde dentro de ajax_login_init()? El primero no puede funcionar porque está en un contexto Ajax.

swissspidy swissspidy
17 ene 2018 14:05:58

He enumerado los archivos en los que están las funciones, como texto descriptivo arriba. El is_page() se usa en el functions.php y sirve para incluir el archivo con las funciones ajax solo cuando es necesario.

Sin Sin
17 ene 2018 14:48:35

@Sin Again, is_page() no funciona en un contexto Ajax. He actualizado mi respuesta en consecuencia.

swissspidy swissspidy
17 ene 2018 14:58:22
0

Recuerda que el nombre de la función 'action' debe estar añadido a la etiqueta wp_ajax_.

function fetchorderrows() { // Esta función se ejecutará al enviar el ajax
  // Haz cosas increíbles aquí todo el día
}

add_action('wp_ajax_fetchorderrows', 'fetchorderrows', 0);
14 abr 2019 23:43:03
1
-1

En caso de que alguien esté utilizando un enfoque basado en clases y tenga problemas con el error 400 en AJAX, puede que necesite mover los manejadores de AJAX fuera de la clase (inténtalo en el archivo principal del plugin) y usar la clase y el método como segundo argumento.

add_action( 'wp_ajax_your_handle', [ 'Class_Name', 'function_name' ] );
add_action( 'wp_ajax_nopriv_your_handle', [ 'Class_Name', 'function_name' ] );
18 nov 2020 11:48:31
Comentarios

No es necesario moverlos fuera de la clase. Simplemente enganchalos a admin_init, para que se ejecuten mientras se gestionan las solicitudes ajax.

Erenor Paz Erenor Paz
18 dic 2020 16:50:41
1
-4

simplemente escribe die; al final como se muestra a continuación...descripción de la imagen

12 nov 2018 15:12:27
Comentarios

Hola Zee Xhan. Bienvenido/a al sitio. Tu respuesta necesita algunas revisiones. Primero, si tu respuesta es código, no publiques una captura de pantalla. En su lugar, publica el código como un fragmento y formatealo como código (usa el botón {}). Esa es probablemente la razón por la que tu respuesta fue votada negativamente y no fue aceptada. También, un poco más de explicación sería útil - como "por qué" simplemente escribir die(), y ¿dónde exactamente va esto en relación con el código en el OP (publicación original)?

butlerblog butlerblog
12 nov 2018 16:46:11