400 solicitud incorrecta en admin-ajax.php solo usando el gancho de acción wp_enqueue_scripts

15

He estado trabajando en ajax últimamente. Los tutoriales que encuentra en la red son muy similares y fáciles de implementar. Pero siempre recibo una mala solicitud 400 en mi ajax-admin.phparchivo.

Después de una búsqueda larga e intensa, ahora descubrí que se debe al tiempo de integración.

Si uso el initgancho de acción para inicializar el script y wp_localize_script, todo funciona bien. Entonces 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' => 'REDIRECT_URL_HERE','loadingmessage' => __('Sending user info, please wait...')));
   add_action('wp_ajax_nopriv_ajaxlogin','ajax_login');
}

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

function ajax_login(){
    //nonce-field is created on page
    check_ajax_referer('ajax-login-nonce','security');
    //CODE
    die();
}

Pero si uso, por ejemplo wp_enqeue_scripts, el gancho de acción, siempre recibo la solicitud incorrecta.

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 adicional y cargarlas solo si son necesarias en una página en particular. Para esto necesito, por ejemplo is_page(). Pero is_page()funciona lo antes posible cuando engancho la función con la inclusión en el parse_querygancho de acción:

funciones.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 para initenganchar en el my-page-test-functions.phparchivo no se activan, supongo, porque initviene antes parse_query.

¿Hay mejores prácticas para organizar esto, por lo que funciona? ¿O cómo puedo solucionar la admin-ajax.phpsolicitud incorrecta cuando uso el wp_enqeue_scriptsgancho de acción?

Pecado
fuente

Respuestas:

13

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

Ese código registra su controlador Ajax, pero cuando solo lo ejecuta wp_enqueue_scripts, ya es demasiado tarde y los wp_ajax_nopriv_ganchos ya están ejecutados.

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' => 'REDIRECT_URL_HERE','loadingmessage' => __('Sending user info, please wait...')));
}

add_action( 'wp_enqueue_scripts','ajax_login_init' );

add_action( 'wp_ajax_nopriv_ajaxlogin','ajax_login' );

function ajax_login(){
  //nonce-field is created on page
  check_ajax_referer('ajax-login-nonce','security');
  //CODE
  die();
}

Editar:

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

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

La is_page()verificación significaba que su archivo de funciones solo se cargaba en esa página específica. ajax_login_init()es llamado y sus scripts en cola. Hasta aquí todo bien.

Ahora su script hace la llamada ajax. Como se mencionó en los comentarios, las llamadas ajax no conocen la página actual en la que se encuentra. Hay una razón por la cual el archivo se encuentra wp-admin/admin-ajax.php. No existe WP_Queryy, por is_page()lo tanto , no funciona durante una solicitud ajax.

Como eso no funciona, sw18_page_specific_functions()no hará nada en un contexto ajax. Esto significa que su archivo de funciones no está cargado y su controlador ajax no existe.

Es por eso que siempre debe incluir ese archivo de funciones y mover ese is_page()cheque dentro ajax_login_init().

Entonces, en lugar de sw18_page_specific_functions() { … }simplemente correr include_once dirname(__FILE__).'/includes/my-page-test-functions.php';directamente. Sin ninguna add_action( 'parse_query' )llamada

swissspidy
fuente
Buena sugerencia. He cambiado eso (sigue siendo 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 utiliza. - Actualmente intento esto con is_page () como se describe anteriormente.
Sin
¿Estás tratando de correr is_page()desde dentro ajax_login()o desde dentro ajax_login_init()? El primero no puede funcionar porque está en un contexto Ajax.
swissspidy
He enumerado los archivos en los que se encuentran las funciones, como el texto descriptivo anterior. Is_page () se usa en functions.php y sirve para incluir el archivo con las funciones ajax solo cuando es necesario.
Sin
@ Sin otra vez, is_page()no funciona en un contexto Ajax. He actualizado mi respuesta en consecuencia.
swissspidy
0

Recuerde tener el nombre de la función 'acción' agregado a la wp_ajax_etiqueta.

function fetchorderrows() { // Want to run this func on ajax submit
  // Do awesome things here all day long
}

add_action('wp_ajax_fetchorderrows', 'fetchorderrows', 0);
Mohd Abdul Mujib
fuente
-3

solo escribe morir; al final como abajo ...ingrese la descripción de la imagen aquí

ZEe XhAn
fuente
8
Hola Zee Xhan Bienvenido al sitio. Su respuesta necesita algunas revisiones. Primero, si su respuesta es código, no publique una captura de pantalla. En su lugar, publique el código como un fragmento y formatee como código (use el botón {}). Esa es probablemente la razón por la cual su respuesta fue rechazada y no aceptada. Además, un poco más de explicación sería útil, como "por qué" simplemente escribe die (), y ¿a dónde va exactamente esto en relación con el código en el OP (publicación original)?
butlerblog