2

I've got an drupal 8 project with an custom module. There I have an controller which returns specific data we need there. In my js file, I have 7 AJAX requests which are called when someone visits the page. The code for the AJAX requests is the same, just the url is different:

$.ajax({
  url: someUrl,
  dataType: 'json',
  type: 'get',
  data: {
    lang: docLang
  }
});

The urls are also some custom ones which are created in our routing.yml file. When I visit the page, all my AJAX requests are done correctly and the result is as expected. But for some reason, it doesn't cache the response so it always takes a while to load the page. In my controller function I collect some data and put it into an array, for example:

$output = [];
foreach ($nodes as $node) {
  $entry = [];
  // do some stuff, collect the data in $entry
  $output['entries'][] = $entry;
}

After it is done with collecting data and fill them into $output['entries'], I create a CacheableJsonResponse and return it to my js:

$response = new CacheableJsonResponse($output);
return $response;

Like this, it doesn't cache the response, so I thought that I probably need to pass some cache data to it. I've changed the code to the following:

$data['#cache'] = array(
  'max-age' => 2592000,
  'contexts' => array(
    'route',
    'user.roles'
  ),
  'tags' => array(
    'node_type:some_type',
    'taxonomy_term_list',
  ),
);

$response = new CacheableJsonResponse($output);
$response->addCacheableDependency(CacheableMetadata::createFromRenderArray($data));

return $response;

It returns everything correctly, but it still doesn't cache the response. I already took a look at the response headers and the following things are written there:

Cache-Control: must-revalidate, no-cache, private
Connection: Keep-Alive
Content-language: de
Content-Type: application/json
Date: Thu, 07 Jun 2018 06:34:25 GMT
Expires: Sun, 19 Nov 1978 05:00:00 GMT
Keep-Alive: timeout=5, max=99
Server: Apache/2.2.32 (Unix) mod_wsgi/3.5 Python/2.7.13 PHP/7.1.8 mod_ssl/2.2.32 OpenSSL/1.0.2j DAV/2 mod_fastcgi/2.4.6 mod_perl/2.0.9 Perl/v5.24.0
Transfer-Encoding: chunked
Vary: 
X-Content-Type-Options: nosniff
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Generator: Drupal 8 (https://www.drupal.org)
X-Powered-By: PHP/7.1.8
X-UA-Compatible: IE=edge

For example the response headers from a cached file:

Accept-Ranges: bytes
Cache-Control: max-age=1209600
Content-Length: 9026
Content-Type: image/jpeg
Date: Thu, 07 Jun 2018 09:14:11 GMT
ETag: "2bc823-2342-553b62ce65880"
Expires: Thu, 21 Jun 2018 09:14:11 GMT
Last-Modified: Fri, 07 Jul 2017 08:39:46 GMT
Server: Apache/2.2.32 (Unix) mod_wsgi/3.5 Python/2.7.13 PHP/7.1.8 mod_ssl/2.2.32 OpenSSL/1.0.2j DAV/2 mod_fastcgi/2.4.6 mod_perl/2.0.9 Perl/v5.24.0
X-Content-Type-Options: nosniff

I don't think that it is correct with the Cache-Control and Expires in the response headers and I guess this is causing the problem. I also tried to change these headers, I did the following tries:

1. $response->headers->set('Cache-Control', 'public');
// This just puts the Cache-Control headers out of the response, which still doesn't cache it.
2. $response->setExpires($tomorrow);
// Here I pass the DateTime for tomorrow, but it just ends in an error for my page. Also the functions setPublic() and stuff do not work for it.
3. $reponse->headers->addCacheControlDirective('public');
   $response->headers->removeCacheControllDirective('private');
// Also calling this stuff directly wont change anything.

None of these things seems to work.

My Questions: How can I cache the responses from my AJAX requests the drupal way? Is it even possible, to cache these responses via drupal? Would you recommend another way to cache it?

  • Cache-Control: is not the problem here, this is only for external caches and configured at admin/config/development/performance. Internally Drupal caches all cacheable responses. You see this in X-Drupal-* response tags, which I can't find in your question? – 4k4 Jun 7 '18 at 7:59
  • @4k4 Thanks for your fast response. I've edited my question and put everything I have in my response headers into it now. But as you can see, there are no X-Drupal-* response tags. The onliest file I found which has this tag is my index file there. But also there is just one entry for it: X-Drupal-Dynamic-Cache: UNCACHEABLE... Is this the reason for not caching those responses? – Markus Jun 7 '18 at 8:31
  • Yes, X-Drupal-Dynamic-Cache is the one for logged in users. If you don't see this header then the cache is disabled. – 4k4 Jun 7 '18 at 9:00
  • Thanks for the hint, visited the page without being logged in now. I have edited my question again to give some more informations. The new response headers are from an image which is being cached. Also there are no X-Drupal-* response tags, but still it is getting cached. Only these AJAX responses are not getting cached and I'm clueless, why it is like that. What is the way to get these X-Drupal-* response headers in my AJAX responses? – Markus Jun 7 '18 at 9:44
  • I don't know how you've disabled the cache, could be code you didn't show or dev settings. Try it on a fresh install, out-of-the-box Drupal caches such responses. – 4k4 Jun 7 '18 at 9:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.