Solicitud Ajax devolviendo una página HTML completa como respuesta
Sé que esto se ha preguntado frecuentemente aquí, pero ninguna de las soluciones que encuentro parece funcionar para mí.
El problema es el siguiente: cada vez que envío el formulario, obtengo un console.log con la respuesta que es una página HTML completa en lugar de un simple mensaje.
Script del backend:
add_action( 'admin_ajax_nopriv_email_verification_form', 'verify_and_sanitize_email_form' );
add_action( 'admin_ajax_email_verification_form', 'verify_and_sanitize_email_form' );
// Callback de verificación de email
function verify_and_sanitize_email_form() {
// Verificar referer
check_ajax_referer( '9pU0Pk7T01', 'security' );
if(empty($_POST) || !isset($_POST['rguroo_email']) || !isset($_POST['rguroo_email_confirmation']) || !isset($_POST['rguroo_desired_action'])) {
echo 'Hay uno o más campos vacíos';
wp_die();
}
$sanitized_email = sanitize_email( esc_html($_POST['rguroo_email'] ));
$sanitized_email_confirmation = sanitize_email( esc_html($_POST['rguroo_email_confirmation'] ));
$desired_action = esc_html($_POST['rguroo_desired_action']);
if(!is_email( $sanitized_email ) || !is_email( $sanitized_email_confirmation )) {
echo 'El email no es válido';
wp_die();
}
if($sanitized_email !== $sanitized_email_confirmation) {
echo 'Los emails no coinciden';
wp_die();
}
if($desired_action !== 'purchase' || $desired_action !== 'renewal' || $desired_action !== 'trial') {
echo 'Error fatal con los radio buttons';
wp_die();
}
if(!isset($_COOKIE['rguroo_form_type'])) {
echo 'Error del servidor';
wp_die();
}
// Lógica de verificación de email de estudiante
$form_type = $_COOKIE['rguroo_form_type'];
if($form_type === 'student') {
$trail = substr($sanitized_email, -4);
if($trail !== '.edu') {
echo 'No es un email de estudiante válido';
wp_die();
}
// Otra lógica específica para universidades aquí
}
setcookie('rguroo_form_action',$desired_action, 14 * DAY_IN_SECONDS);
setcookie('rguroo_form_email', $sanitized_email, 14 * DAY_IN_SECONDS);
echo "success";
wp_die();
}
Javascript del frontend:
jQuery(document).ready(function () {
jQuery('form#email-verification').on( 'submit', function () {
var form_data = jQuery(this).serializeArray();
form_data.push( { "name" : "security", "value" : ajax_info.ajax_nonce } );
jQuery.ajax({
url : ajax_info.ajax_url,
type : 'post',
data : form_data,
success : function( response ) {
console.log(response);
if(response !== 'success') {
jQuery('.error').innerHTML = response;
} else {
location.reload();
}
},
fail : function( err ) {
jQuery('.error').innerHTML = "No se puede contactar al servidor";
}
});
return false;
});
});
Formulario (usado en un shortcode):
function output_email_verification() {
return '<form action="'.esc_url( admin_url("admin-ajax.php") ).'" method="post" id="email-verification">
<p class="error">'.$error.'</p>
<input type="radio" label="Comprar acceso por 12 meses" value="purchase" name="rguroo_desired_action" checked>Comprar acceso por 12 meses</input>
<input type="radio" label="Renovar cuenta" name="rguroo_desired_action" value="renewal">Renovar cuenta</input>
<input type="radio" label="Crear cuenta de prueba" name="rguroo_desired_action" value="trial">Crear cuenta de prueba</input>
<p class="form-subtext">* indica campo obligatorio</p>
<p>Dirección de email*</p>
<input type="text" name="rguroo_email" required>
<p>Reingresa dirección de email*</p>
<input type="text" name="rguroo_email_confirmation" required>
<input type="hidden" name="action" value="email_verification_form">
<input type="submit" value="Enviar">
</form>';
}
Lo que sé: no hay un problema con jQuery enviando el post (o al menos haciendo la solicitud post). Al enviar, jQuery envía el post con todos los parámetros correctos. También sé que no estoy usando diferentes nonces. He intentado colocar error_logs() por toda la función callback, pero ninguno se mostró en debug.log. Esto me lleva a creer que el callback nunca se llama realmente, pero no sé por qué. Además, incluso si hago una prueba que debería fallar, jQuery todavía lo lee como éxito.
He perdido todo el día con este formulario y me siento como un idiota. ¿Podría alguien con más neuronas que yo decirme dónde me estoy equivocando?
Muchas gracias.

No es eso. Ya hay una acción. Del formulario: <input type="hidden" name="action" value="email_verification_form">
, del javascript: var form_data = jQuery(this).serializeArray();
. Se incluye cuando serializo el formulario. Solo como comprobación, utilicé las herramientas de desarrollo y revisé los parámetros que se enviaban con mi post. Como puedes ver en esta captura de pantalla, los parámetros se configuran y envían correctamente

Una llamada a esta función complementa la función die() de PHP. La diferencia es que se mostrará HTML al usuario en el caso de una solicitud web típica
Tomado de aquí
¿Has intentado usar die()
en lugar de wp_die()
o exit()
?

Algunos problemas en tu código como un hook de ajax y la acción del formulario en shortcode
Cambia tu código y prueba
Código proporcionado abajo
functions.php
function enqueue_scripts() {
// Cargar CSS
//wp_enqueue_style('wp-news-search', plugins_url('/css/wp-news-search.css', __FILE__));
// Cargar y localizar JS
wp_enqueue_script('ajax-script', get_template_directory_uri().'/js/wp-news-search_query.js', array('jquery'), null, true);
wp_localize_script('ajax-script', 'ajax_info',
array('ajax_url' => admin_url('admin-ajax.php'),
'security' => wp_create_nonce('9pU0Pk7T01'),
));
}
add_action('wp_ajax_no_email_verification_form', 'verify_and_sanitize_email_form');
add_action('wp_ajax_email_verification_form', 'verify_and_sanitize_email_form');
// Callback de verificación de email
function verify_and_sanitize_email_form() {
// Verificar referencia
check_ajax_referer('9pU0Pk7T01', 'security');
parse_str($_POST['data'], $data);
if(empty($_POST) || !isset($data['rguroo_email']) || !isset($data['rguroo_email_confirmation']) || !isset($data['rguroo_desired_action'])) {
echo 'Hay uno o más campos vacíos';
wp_die();
}
$sanitized_email = sanitize_email(esc_html($data['rguroo_email']));
$sanitized_email_confirmation = sanitize_email(esc_html($data['rguroo_email_confirmation']));
$desired_action = esc_html($data['rguroo_desired_action']);
if(!is_email($sanitized_email) || !is_email($sanitized_email_confirmation)) {
echo 'El email no es válido';
wp_die();
}
if($sanitized_email !== $sanitized_email_confirmation) {
echo 'Los emails no coinciden';
wp_die();
}
if($desired_action !== 'purchase' || $desired_action !== 'renewal' || $desired_action !== 'trial') {
echo 'Error fatal con los botones de radio';
wp_die();
}
if(!isset($_COOKIE['rguroo_form_type'])) {
echo 'Error del servidor';
wp_die();
}
// Lógica de verificación de email de estudiante
$form_type = $_COOKIE['rguroo_form_type'];
if($form_type === 'student') {
$trail = substr($sanitized_email, -4);
if($trail !== '.edu') {
echo 'No es un email válido de estudiante';
wp_die();
}
// Otra lógica específica de universidad aquí
}
setcookie('rguroo_form_action',$desired_action, 14 * DAY_IN_SECONDS);
setcookie('rguroo_form_email', $sanitized_email, 14 * DAY_IN_SECONDS);
echo "success";
wp_die();
}
add_shortcode('wp_news_search','wp_news_search_form');
function wp_news_search_form() {
return '<form id="email-verification">
<p class="error">'.$error.'</p>
<input type="radio" label="Comprar acceso de 12 meses" value="purchase" name="rguroo_desired_action" checked>Comprar acceso de 12 meses</input>
<input type="radio" label="Renovar cuenta" name="rguroo_desired_action" value="renewal">Renovar cuenta</input>
<input type="radio" label="Crear cuenta de prueba" name="rguroo_desired_action" value="trial">Crear cuenta de prueba</input>
<p class="form-subtext">* indica campo requerido</p>
<p>Dirección de email*</p>
<input type="text" name="rguroo_email" required>
<p>Vuelve a escribir la dirección de email*</p>
<input type="text" name="rguroo_email_confirmation" required>
<input type="hidden" name="action" value="email_verification_form">
<input type="submit" value="Enviar">
</form>';
}
Js
jQuery(document).ready(function () {
jQuery('#email-verification').submit(function (event) {
event.preventDefault();
var form_data = jQuery(this).serialize();
jQuery.ajax({
url : ajax_info.ajax_url,
type : 'post',
data: {
action: 'email_verification_form',
data: form_data,
security: ajax_info.security
},
success : function( response ) {
console.log(response);
if(response !== 'success') {
jQuery('p.error').html(response);
} else {
location.reload();
}
},
fail : function( err ) {
jQuery('.error').innerHTML = "No se puede contactar con el servidor";
}
});
return false;
});
});

Esto puede funcionar. Encuentra tu div por el nombre de clase desde la respuesta y obtén el innerHTML de este.
success : function( response ) {
var error = $(response).find('.error-div')[0].innerHTML;
if(response !== 'success') {
jQuery('.error').innerHTML = error;
}
