views:

183

answers:

4

I have different logic in an action depends if the request is an AJAX one or not.
(For AJAX logins, I do not need to redirect after successful login, which is not the case in normal login, for example).
What is the best way, beside checking the headers for X-Requested-With: XMLHttpRequest
Is there a flag or something?

+1  A: 

Usually I create a two entry points for my app: /index.php and /ajax/index.php. They both share a common bootstrapper but in the ajax.php I set a FrontController param to say that this request is an ajax request.

I can then just check in with the Request object.

if($this->getRequest()->getParam('ajax')) {
    // Ajax request
} else {
    // Normal request
}
smack0007
+6  A: 

This method works by checking for a header which is set by almost (if not) all of the major JS libraries, including jQuery and YUI.

$this->getRequest()->isXmlHttpRequest() //returns true if is XHR

The method detailed by smack0007 is guaranteed to be accurate, but the method above is fine if the connection is always made by a library which sets the header. It is probably not suitable for a public API.

David Caunt
Ah, barely beat me to it. Plus an upvote for a good explanation (plus caveats)
Brett Bender
This *is* “checking the headers for X-Requested-With: XMLHttpRequest”, though.
bobince
True, but if you are using a javascript framework that does reliably set those headers (and only that JS library for ajax calls) then you should be able to rely on the method. The zend documentation does specify, for instance, this method "Should work with Prototype/Script.aculo.us, possibly others." A little testing with your framework of choice should be sufficient. If any custom JS / Ajax is used, though, I agree that somebody may encounter issues with this method.
Brett Bender
@ bobince Not entirely true. It is a wrapper, and I don't have to do the actual check in MY code. So, if there will be a different method in the future, I won't have to re-factor my controllers.
Itay Moav
I agree with bobince and smack's suggestions of a different route or parameter for detection. You might find AjaxContext and ContextSwitch helpers useful. I think the header is pretty unlikely to change, and just as we rely on other things to be constant, a small refactoring of code is much more convenient than investing time (small or large) in extra code.
David Caunt
+1  A: 

The Zend_Controller_Request_Http class has a method called isXmlHttpRequest() that should tell you whether or not the request is from Javascript (ajax).

(Out of practice coding but) Probably would be something like this in your action:

if($this->getRequest()->isXmlHttpRequest()){
    //is ajax
}
else{
    //regular request
}
Brett Bender
+3  A: 

There isn't a reliable method to tell them apart; browsers use pretty much the same HTTP code for both XMLHttpRequest and normal access.

With the different browser handling of custom headers, and potential proxy interference, I would not trust the X-Requested-With header to get through in all cases. (And that's all isXmlHttpRequest actually looking for.)

Instead, I'd use a parameter (?ajax=1) or other method that generates a unique URL such as smack's suggestion.

bobince