evilcelery
evilcelery

Reputation: 16139

Symfony 1.4: How do I get caching working with ajax requests?

I have some actions that are meant to be used in ajax requests.

If I view the page in the browser, the response is cached as it should be. However, in ajax requests it's not.

The request method is GET and without GET params.

sfViewCacheManager doesn't even call isXMLHttpRequest() so it's quite confusing why this isn't working...

Is there a setting somewhere for enabling cached ajax requests?

Upvotes: 0

Views: 2357

Answers (3)

AhmedLocalhost
AhmedLocalhost

Reputation: 1

Symfony always disable Cache when POST or GET or other HTTP Headers are sent with a page.

So your AJAX query is not cached because you are sending GET parameters to page you want to be cached.

The best way to test that is : add GET params and view page "in browser" as you said, and you ll see that Cache will not work.

So disable POST and GET or other Header PUT DEL from Ajax call and cache will work fine.

To disable Get/Post : http://www.panteo.net/article/en/1/developpement-symfony-php/cache-symfony-and-appels-ajax.html

Upvotes: 0

pluk77
pluk77

Reputation: 144

The following did the trick for me when caching jQuery autocomplete responses:

  • Remove the additional timestamp parameter from the jQuery script

    replace:

    var extraParams = {
      timestamp: +new Date()
    };
    

    by:

    var extraParams = {};
    
  • Enable cache in cache.yml, with layout. Without the layout it did not seem to work:

    loginFacility:
      enabled:     true
      with_layout: true
      lifetime:    86400
    
  • Remove the Pragma header in the action, as this was automatically set to 'no-cache':

    $this->getResponse()->setHttpHeader("Pragma", "");
    

My action now looks like this:

public function executeLoginFacility(sfWebRequest $request)
{
  $this->getResponse()->setContentType('application/json');
  $this->getResponse()->setHttpHeader("Pragma", "");
  $facilities =  Doctrine_Core::getTable('Facility')->findLoginFacilitiesForAutocomplete(
        $request->getParameter('q'),
        $limit);

  return $this->renderText(json_encode($facilities));
}

Now, when doing a lot of auto-completes, the responses are cached by Symfony and firefox is retrieving them from its own cache. At least that what it looks like in Firebug.

I found that adding a template to the mix instead of returning strait from the action only resulted in a larger cached file in the Symfony cache. I could not see a benefit.

Upvotes: 1

evilcelery
evilcelery

Reputation: 16139

It's not 100% ideal but I've come up with a solution to this. It seems that caching only works by default when you use a template. I was responding via return $this->responseText($json);.

Responding via a minimal PHP template got the caching running.

#jsonSuccess.php
<?php echo $json ?>

Would still be good to know if there's a way of making responseText trigger the caching mechanism as it would be slightly faster than running through a template.

Funny enough, the caching now even works while use GET query params. I think this may have been something they enabled in Symfony 1.3/1.4.

In order to tell what was being cached, I added a 'created_at' header to the response when viewing in debug mode.

Upvotes: 0

Related Questions