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?