The right way to do an ajax post in Wordpress

Nov 16, 2013

For a long time making ajax calls in Wordpress was very confusing to me. After reading the Codex and several articles about it, I think I understand it a little better now. When you stop fighting Wordpress and do it the “Wordpress way” it’s not too bad. Here’s a little plugin that demonstrates how to do an ajax post from the front end the right way.

Now let’s walk through it.

Wordpress has a built-in ajax handler located at /wp-admin/admin-ajax.php. This is set up so that you can post to that file and pass a custom “action” variable in your $_POST array. The important part of that file looks like this:

This code makes two custom action hooks available to you: one for logged-in users and one for regular users. The action hooks are named after the action you provided. So if my action is “do_cool_stuff”, then the corresponding action hooks are called “wp_ajax_do_cool_stuff” and “wp_ajax_nopriv_do_cool_stuff”.

The do_action() call here invokes all functions attached to that action hook. So now all we have to do is write a function (which will be our own custom ajax handler for this call), and then attach it to this action hook. We do that like so:

My ajax handler function doesn’t actually do much. It simply verifies the nonce to make sure the request is coming from the right place, and then prints out the the posted variables:

publicfunctionfrontend_ajax_handler(){global$wpdb;// now you can access the database
// make sure the request is legit
if(!wp_verify_nonce($_POST['nonce'],'my-frontend-action-nonce')){exit;}// print out the POST array
print_r($_POST);exit;}

You could do whatever you want here. One important thing to note is that you have to call exit() or die() here after you echo whatever you want to return to the calling javascript function. Otherwise admin-ajax.php will echo a 0 or 1 which gets added to the end of your response text, and that could possibly break stuff on the other end.

Since we put our javascript in a separate file, we want to enqueue that script so that it loads on the page where we need to call it. We can also define a global ajax object that we can use to pass variables around with. This is a little cleaner than having to echo out variables wrapped in php tags into our javascript.

Now all that’s left is the javascript which actually makes the ajax call. Here I’m simply grabbing a form and posting its data to my ajax handler. First I serialize the form fields, then I add my action and nonce variables to it, and then I post it. When the response comes back from the handler (which is just the post variables), I log it to the console so we can see that it came back correctly. Then I return false to prevent the page from reloading (the form has no action attribute so by default it will submit to the page it’s on which would reload the page).