Detecting Ajax Events on the Server
read 14 commentsWhen 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.
- if ( !remote ) {
- xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
- }
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:
- function is_xhr() {
- return @ $_SERVER[ 'HTTP_X_REQUESTED_WITH' ] === 'XMLHttpRequest';
- }
- if( is_xhr() ){
- // respond to Ajax request
- } else {
- // respond to normal request
- }
Sinatra and Ruby on Rails have special shortcuts already built in:
- if request.xhr?
- # respond to Ajax request
- else
- # respond to normal request
- end
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:
- <form id="email_form" action="email.php" method="POST">
- <p>
- <label for="email">Email Address: </label><br />
- <input type="text" name="email" id="email" value="" />
- </p>
- <p>
- <input type="submit" value="Subscribe" />
- </p>
- </form>
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
- // Call our special email subscribe function
- $success = subscribe( $email );
- ?>
- <!DOCTYPE html>
- <html>
- <head>
- <title>Email Signup</title>
- <style type="text/css">
- .success { color: green }
- .error { color: red }
- </style>
- </head>
- <body>
- <?php if( $success ): ?>
- <div class="success">Your Signup Is Successful! Thank you!</div>
- <?php else: ?>
- <div class="error">Something went wrong.
- Please click your browser's back button and try again.</div>
- <?php endif; ?>
- </body>
- </html>
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:
- <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
- <script type="text/javascript" charset="utf-8">
- $("#email_form")
- // Cancel the normal submission of the form
- e.preventDefault();
- // perform validation; not shown
- // Make our request and expect JSON in return
- } else {
- $("#notice").html("<div id='error'>There was an error. Please make sure your email is valid and try again.</div>");
- }
- }, 'json');
- });
- });
- </script>
Finally, we replace the initial PHP code block in our email.php file to take advantage of the Ajax submission:
- <?php
- function is_xhr() {
- return @ $_SERVER[ 'HTTP_X_REQUESTED_WITH' ] === 'XMLHttpRequest';
- }
- // Call our special email subscribe function
- $success = subscribe( $email );
- if( is_xhr() ){
- // Not explicitly needed, but we like being accurate, right?:
- if( $success ){
- } else {
- }
- }
- // ... the rest of our original PHP page
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.
















Hey, thanks for this! I've been passing "{ ajax : true }" whilst developing my project app. This will save me a bit of hassle :)
If you’re ardealy sold on the idea of promises, you might consider using this library I ported from Tyler Close’s Waterken project in conjunction with the Google Caja team. It’s a very well-designed promise API that’s getting some traction in the CommonJS community. I also understand there might ardealy be efforts within Mozilla to build the Node API within Spidermonkey instead of V8. There’s also GPSEE, a CommonJS implementation, which Wes Garland mentioned he was getting to work with the Node API’s as well.
Likewise, I've also been passing a boolean. I'll change that now!
Well @Jon and @Aaron I am glad the article helped you out! Its the little things like this that go a long way in keeping code clean and readable.
Thank you soo much for sharing this. I'm new to jQuery and Ajax. So, I have been looking to something like this tutorial and your is very informative and to the point. Thanks for sharing. I will definitely use this on my site: http://www.kumarphotography.com.
Mark Kumar
I have make an exzample:http://www.denisdeng.com/exzample/ajax-detect/email.html.
I do not really like how the PHP and JS duplicate themselves creating success or failure html messages. Say, you need to update the message, or the markup. You need to do that twice. I understand you want to keep the examples simple, but I'm missing here a note, that this is not the best approach (pointing people who want to learn eg. to Resig's templating). After all, this blog is about learning good practices :)
Django has a similar feature:
is_ajax(), that is a method ofHttpRequest.For example in a view:
Great article!
This is great, thanks for posting such a nice article. Actually, it looks like the whole site is filled with jquery gold.. awesome!
Using @ to suppress errors is slow and probably the wrong thing to use in this context. Might wanna use
isset()instead:Well typed, I was just about to write the same thing!
On a similar note,
$email = trim( $_POST['email'] );could be changed to
$email = isset( $_POST['email'] )? trim( $_POST['email'] ): '';The jQuery form plugin doesn't send XMLHttpRequest header when an upload is posted because of using an iframe for file upload.
Hi there,
Thanks a lot for your post. I've noticed a problem and perhaps you know the solution??? IE7 is not setting the variable
$_SERVER[ 'HTTP_X_REQUESTED_WITH' ]so when I look for that variable in PHP, in IE7 it cannot be found!!. The XHR request status is set to 200 -success-, but the variable'HTTP_X_REQUESTED_WITH'has not been set!. this is only when using IE 7.Any help is appreciated!.
I prefer this: