Monday, October 21, 2013

8:49 AM
In an effort to make client-side code as unobtrusive as possible, we typically take the approach of first building applications without JavaScript.  This practice makes sure all of our anchor tags have legitimate URLs in their href attribute.  We can then attached event handlers to the anchors that should trigger AJAX requests.  Then it’s simply a matter of reading the href attribute of the clicked item, and setting that as the source for the AJAX request.  Nothing new here…

  var src = $(this).attr('href');
  //AJAX request here
  return false;

But often we want to fork our controller logic based on whether or not a request was made via AJAX.  For example, no reason getting data we won’t be using in the AJAX response (like navigations, user data, etc).  Plus we want to load AJAX-specific views to return appropriate HTML snippets, or JSON objects.  

So we just test to see if $_SERVER['HTTP_X_REQUESTED_WITH'] equals “xmlhttprequest” which seems to work consistently for all of the browsers on our checklist (note, this is sent when an AJAX request is made via jQuery – and most other JavaScript frameworks – but best not to assume).  We set this as a constant in our bootstrap file, allowing us to refer to it throughout our code.

define('IS_AJAX', isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest');

One issue this brought up though was caching of AJAX requests, especially in Internet Explorer.  When updating our HTML with the server’s response, we often saw the entire page load into the target div.  IE was aggressively caching the AJAX request.  Simply setting JQuery to disable caching was the easy fix.

$.ajaxSetup({ cache: false });

Another simple approach would be to add a parameter to all of your AJAX requests. And even though the method outlined above is not tamper proof (not that anything really is), it seems a bit more reliable to me than the AJAX parameter approach, especially when you have many hands in the jar during the application development cycle. 

For more complex application development, the majority of PHP frameworks out there provide this via other means (CakePHP’s RequestHandler for example). But for our home-baked, lightweight Facebook Application frameworks, this works nicely.