Detecting Ajax Events on the Server

When working with an Ajax-enhanced website, it's generally a good idea to provide a regular request fallback for any core functionality of the site. When you work to ensure that a fallback is in place, you will be faced with determining when a particular request is an Ajax request or just a normal page request. In most situations, it's considered a best practice to build your site without Ajax first, adding the Ajax functionality afterward so the fallbacks are in place from the beginning.

Fortunately, jQuery makes it super easy to differentiate the Ajax requests from normal page views.

X-Requested-With Header

If you were to browse the jQuery source, you would see that jQuery adds a special HTTP header to (almost) every Ajax request it makes with $.ajax(), $.get(), $.getJSON(), $.post() and .load() methods.

[js]if ( !remote ) { xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); } [/js]

Keep in mind, though, that the header is not sent with $.getScript() or any JSONP request made with $.ajax() or $.getJSON(), since they aren't technically Ajax requests.

Detection on the Server

By checking for this header, you can easily determine on the server if the request was initiated by jQuery. Each server-side language and web server combination will give you different ways of accessing this header, but let's look at a few.

In PHP, you can use this function to determine the type of request:

[php]function is_xhr() { return @ $_SERVER[ 'HTTP_X_REQUESTED_WITH' ] === 'XMLHttpRequest'; } if( is_xhr() ){ // respond to Ajax request } else { // respond to normal request } [/php]

Sinatra and Ruby on Rails have special shortcuts already built in:

[ruby]if request.xhr? # respond to Ajax request else # respond to normal request end [/ruby]

Since other libraries outside of jQuery also set the X-Requested-With header, many server languages have special support for reading it. Check the documentation for your favorite server language to see if it has any convenience methods for detecting an Ajax request.

A Small Example

Ok, let's apply this knowledge to add Ajax to a simple email signup form. Here is our existing HTML:

[html]


[/html]

And here is the existing email.php (Note: on a normal error you might redirect back to show a message, or render the form again. This is for example only):

[php]< ?php $email = trim( @$_POST['email'] ); // Call our special email subscribe function $success = subscribe( $email ); ?> < !DOCTYPE html> Email Signup < ?php if( $success ): ?>
Your Signup Is Successful! Thank you!
< ?php else: ?>
Something went wrong. Please click your browser's back button and try again.
< ?php endif; ?> [/php]

The previous two pages work together to provide a simple signup functionality, without JS or Ajax involvement.

Now let's add the Ajax. We’ll add the following to the form page:

[js] [/js]

Finally, we replace the initial PHP code block in our email.php file to take advantage of the Ajax submission:

[php]< ?php function is_xhr() { return @ $_SERVER[ 'HTTP_X_REQUESTED_WITH' ] === 'XMLHttpRequest'; } $email = trim( $_POST['email'] ); // Call our special email subscribe function $success = subscribe( $email ); if( is_xhr() ){ // Not explicitly needed, but we like being accurate, right?: header('Content-type: application/json'); if( $success ){ echo json_encode( array( 'success' => true ) ); } else { echo json_encode( array( 'error' => true ) ); } exit(); // We don't need to render anything else } // ... the rest of our original PHP page [/php]

Conclusion

That's it! A few lines of code, and your server side code can now render different content depending on how the request was generated. Now that you know how to detect jQuery Ajax events, you no longer need to resort to passing ajax: true as data on your requests or calling a separate file altogether.