So I'm still learning around WordPress and can't seem to figure out how to properly hook a nonce into a AJAX Form that I have created.
Here I am hooking and localizing the js file and defining a update_profile_validation
nonce [WORKS]:
function enqueue_scripts()
{
if (!is_admin()) {
wp_register_script('profile_edit_submit', content_url() . '/mu-plugins/fleishmanhillard/scripts/frontend-profile-edit.js', ['jquery'], '', true);
wp_localize_script( 'profile_edit_submit', 'profile_edit', [
// This will generate the admin URL that we can use on the front-end of our website
'ajax_url' => admin_url('admin-ajax.php'),
// Pass in a custom nonce name for JS
'nonce' => wp_create_nonce('update_profile_validation'),
]);
wp_enqueue_script('profile_edit_submit');
}
}
add_action('wp_enqueue_scripts', 'enqueue_scripts');
This method is used to update the user content [WORKS]:
function ajax_update_profile_post($args)
{
check_ajax_referer('update_profile_validation', 'my_nonce');
update_profile_post($args);
wp_die();
}
add_action( 'wp_ajax_update_profile_post', 'ajax_update_profile_post' );
function update_profile_post($args = [])
{
if (!$args) {
return;
}
// If the server request is POST, proceed to update post
if (strtolower($_SERVER['REQUEST_METHOD']) === "post") {
wp_update_post($args);
}
}
Here is my AJAX form submission [WORKS]:
(function ($) {
$(function($) {
$('#profile_update').on('submit', function(e) {
$.ajax({
type: 'POST',
url : profile_edit.ajaxurl,
data: $('#profile_update').serialize() +
'&my_nonce=' + profile_edit.nonce +
'&action=update_profile_post'
});
return false;
});
});
})(jQuery);
Here is the final part of my form:
<?php if ($profile->get_edit_post_link()):
// Set the post field content field
$post_content = $_POST['content'];
ajax_update_profile_post([
'ID' => $profile->get_id(),
'post_content' => $post_content,
]);
?>
<form action="" id="profile_update" method="POST">
<input type="text" name="content" id="post_content">
<button type="submit"><?= 'Update Post' ?></button>
<?php wp_nonce_field('update_profile_validation', 'my_nonce'); ?>
</form>
<?php endif;
So the form works and the field submits and all, but I'm having a difficult time understanding how to apply a proper nonce to the form.. All assistance would be appreciated!
So I'm still learning around WordPress and can't seem to figure out how to properly hook a nonce into a AJAX Form that I have created.
Here I am hooking and localizing the js file and defining a update_profile_validation
nonce [WORKS]:
function enqueue_scripts()
{
if (!is_admin()) {
wp_register_script('profile_edit_submit', content_url() . '/mu-plugins/fleishmanhillard/scripts/frontend-profile-edit.js', ['jquery'], '', true);
wp_localize_script( 'profile_edit_submit', 'profile_edit', [
// This will generate the admin URL that we can use on the front-end of our website
'ajax_url' => admin_url('admin-ajax.php'),
// Pass in a custom nonce name for JS
'nonce' => wp_create_nonce('update_profile_validation'),
]);
wp_enqueue_script('profile_edit_submit');
}
}
add_action('wp_enqueue_scripts', 'enqueue_scripts');
This method is used to update the user content [WORKS]:
function ajax_update_profile_post($args)
{
check_ajax_referer('update_profile_validation', 'my_nonce');
update_profile_post($args);
wp_die();
}
add_action( 'wp_ajax_update_profile_post', 'ajax_update_profile_post' );
function update_profile_post($args = [])
{
if (!$args) {
return;
}
// If the server request is POST, proceed to update post
if (strtolower($_SERVER['REQUEST_METHOD']) === "post") {
wp_update_post($args);
}
}
Here is my AJAX form submission [WORKS]:
(function ($) {
$(function($) {
$('#profile_update').on('submit', function(e) {
$.ajax({
type: 'POST',
url : profile_edit.ajaxurl,
data: $('#profile_update').serialize() +
'&my_nonce=' + profile_edit.nonce +
'&action=update_profile_post'
});
return false;
});
});
})(jQuery);
Here is the final part of my form:
<?php if ($profile->get_edit_post_link()):
// Set the post field content field
$post_content = $_POST['content'];
ajax_update_profile_post([
'ID' => $profile->get_id(),
'post_content' => $post_content,
]);
?>
<form action="" id="profile_update" method="POST">
<input type="text" name="content" id="post_content">
<button type="submit"><?= 'Update Post' ?></button>
<?php wp_nonce_field('update_profile_validation', 'my_nonce'); ?>
</form>
<?php endif;
So the form works and the field submits and all, but I'm having a difficult time understanding how to apply a proper nonce to the form.. All assistance would be appreciated!
Share Improve this question edited Mar 31, 2020 at 12:33 DevSem asked Mar 31, 2020 at 4:08 DevSemDevSem 2092 silver badges11 bronze badges1 Answer
Reset to default 3You just need to send the nonce along with your AJAX data:
$.ajax({
type: 'POST',
url : profile_edit.ajaxurl,
data: $('#profile_update').serialize() +
'&my_nonce=' + profile_edit.nonce +
'&action=update_profile_post', // don't forget the action name!
});
Alternatively, since you're using jQuery's serialize()
function, you could just add the nonce directly in the form:
<?php wp_nonce_field( 'update_profile_validation', 'my_nonce' ); ?>
Then since you're doing AJAX, you'd use check_ajax_referer()
to verify the submitted nonce:
function update_profile_post() {
check_ajax_referer( 'update_profile_validation', 'my_nonce' );
// ... the rest of your code.
wp_die();
}
Check the WordPress developer site here for more details.
Additionally, I'd use two functions instead of calling the same update_profile_post()
from the form and the AJAX callback. Something like this would do:
function ajax_update_profile_post() {
check_ajax_referer( 'update_profile_validation', 'my_nonce' );
// call update_profile_post() with submitted parameters
// or call wp_update_post() directly
wp_die();
}
add_action( 'wp_ajax_update_profile_post', 'ajax_update_profile_post' );
function update_profile_post( $args ) {
// call wp_update_post( $args ) here
// or just call wp_update_post() directly in your form
}
Also, the REST API offers a more structured and predictable way to interact with your site, so you should consider using the API to handle your AJAX actions. In fact, there's an existing endpoint for updating a post. :)
UPDATE
If you haven't, check out the AJAX guide on the WordPress' plugin handbook. You'll get more information there that I didn't include in this answer. :)
About that
// don't forget the action name!
, it just means that you need to send the action name along with the AJAX data so that WordPress knows which function should be called, which is the aboveajax_update_profile_post()
or theupdate_profile_post()
as in the question. And if you didn't send the action name, then you'd likely get the famous400 Bad Request
error with the output0
(which is why the REST API is better since it can tell you the exact error).And by action name, I'm referring to the
<action>
part as inwp_ajax_<action>
, which in the question isupdate_profile_post
."Are we missing a
wp_ajax_no_priv
action?" — Yes, if you're allowing non-authenticated users (or those who're not logged in) to use the form.