WordPress Ajax siempre devuelve un error 404
Obtuve este código de un tutorial. No logro hacer que funcione.
HTML (home.php)
<form name="myform" id="myform" action="" method="POST">
<!-- El campo del formulario para el Nombre -->
<label for="name" id="name_label">Nombre</label>
<input type="text" name="name" id="name" size="30" value=""/>
<br>
<!-- El campo del formulario para el Email -->
<label for="email" id="email_label">Email</label>
<input type="text" name="email" id="email" size="30" value=""/>
<br>
<!-- El botón de Enviar -->
<input type="submit" name="submit" value="Enviar">
</form>
<!-- Aquí mostraremos los resultados de process.php -->
<div id="results"><div>
PHP (functions.php)
function myform(){
echo "Formulario enviado exitosamente: <br>Tu nombre es <b>".$_POST['name']."</b> y tu email es <b>".$_POST['email']."</b><br>";
}
add_action('wp_ajax_myform', 'myform');
add_action('wp_ajax_nopriv_myform', 'myform');
Javascript (header.php)
<script type="text/javascript">
jQuery(document).ready(function(){
jQuery("#myform").validate({
debug: false,
rules: {
name: "required",
email: {
required: true,
email: true
}
},
messages: {
name: "Por favor, déjanos saber quién eres.",
email: "Un email válido nos ayudará a contactarte.",
},
submitHandler: function(form) {
// hacer otras cosas para un formulario válido
jQuery.post('/wp-admin/admin-ajax.php', jQuery("#myform").serialize(), function(data) {
jQuery('#results').html(data);
});
}
});
});
</script>

Esto fue muy frustrante de resolver. Pasé horas en este problema y descubrí que tu inconveniente está en este campo de entrada:
<input type="text" name="name" id="name" size="30" value=""/>
Intenta cambiar el nombre del campo de entrada a cualquier cosa excepto "name", por ejemplo:
<input type="text" name="user_name" id="name" size="30" value=""/>

Sí, hay una lista de nombres reservados, donde si usas uno en tus formularios, WP fallará, generalmente sin un buen mensaje de error.

Increíble. A WP no le gusta el término usado como nombre para una propiedad del cuerpo POST, ¡así que lanza un 404?!?!?! Tan estúpido.

Aquí están: https://codex.wordpress.org/Reserved_Terms

Si estás obteniendo un error 404 en la solicitud AJAX, entonces tu ruta está incorrecta. Usa admin_url
para construir la ruta en lugar de codificarla manualmente.
jQuery.post(<?php admin_url('admin-ajax.php') ?>, // ...
Probablemente sea mejor imprimir la URL de administración en una variable de Javascript mediante wp_localize_script
que imprimirla directamente en la plantilla. Por ejemplo:
wp_enqueue_script('jquery');
wp_localize_script( 'jquery', 'my_ajax_vars', array(
'ajaxurl' => admin_url( 'admin-ajax.php' )
);
Generalmente es mejor registrar y encolar los scripts en lugar de escribirlos directamente en las plantillas, especialmente en header.php
. Tal como está escrito, tu Javascript se carga en cada página y es poco probable que se necesite en todas.

Primero que nada, sanitiza todos tus datos.
En segundo lugar, prefiero hacerlo así:
jQuery(function($){
$("#myform").validate({
debug: false,
rules: {
name: "required",
email: {
required: true,
email: true
}
},
messages: {
name: "Por favor dinos quién eres.",
email: "Un email válido nos ayudará a contactarte.",
},
submitHandler: function(form) {
// hacer otras cosas para un formulario válido
// si no tienes tu script localizado y lo agregarás en header.php (no es una buena práctica)
$.post(
'<?php echo admin_url('admin-ajax.php'); ?>',
form.serialize(),
function(data){
// solo para verificar los datos
console.log(data);
$('#results').html(data);
}
});
jQuery.post('/wp-admin/admin-ajax.php', jQuery("#myform").serialize(), function(data) {
jQuery('#results').html(data);
});
}
});
});
Y en tu archivo php (functions.php):
Asegúrate de agregar die(); al final de las funciones.
function myform(){
echo "Formulario enviado exitosamente: <br>Tu nombre es <b>".$_POST['name']."</b> y tu email es <b>".$_POST['email']."</b><br>";
die();
}
add_action('wp_ajax_myform', 'myform');
add_action('wp_ajax_nopriv_myform', 'myform');
