diff --git a/core/lib/Drupal/Core/Cache/CacheableAjaxResponse.php b/core/lib/Drupal/Core/Cache/CacheableAjaxResponse.php new file mode 100644 index 0000000000000000000000000000000000000000..996e674d8e029d680578632a68234202642c48cc --- /dev/null +++ b/core/lib/Drupal/Core/Cache/CacheableAjaxResponse.php @@ -0,0 +1,21 @@ +<?php + +namespace Drupal\Core\Cache; + +use Drupal\Core\Ajax\AjaxResponse; + +/** + * A AjaxResponse that contains and can expose cacheability metadata. + * + * Supports Drupal's caching concepts: cache tags for invalidation and cache + * contexts for variations. + * + * @see \Drupal\Core\Cache\Cache + * @see \Drupal\Core\Cache\CacheableMetadata + * @see \Drupal\Core\Cache\CacheableResponseTrait + */ +class CacheableAjaxResponse extends AjaxResponse implements CacheableResponseInterface { + + use CacheableResponseTrait; + +} diff --git a/core/modules/page_cache/tests/src/Functional/PageCacheTest.php b/core/modules/page_cache/tests/src/Functional/PageCacheTest.php index 5164c57948990d554adbdc8527f43f30edaaa1dd..ef08a5f54bca6ef1acd43fefa3499f88e83ab1e8 100644 --- a/core/modules/page_cache/tests/src/Functional/PageCacheTest.php +++ b/core/modules/page_cache/tests/src/Functional/PageCacheTest.php @@ -127,6 +127,7 @@ public function testQueryParameterFormatRequests() { $accept_header_cache_url = Url::fromRoute('system_test.page_cache_accept_header'); $accept_header_cache_url_with_json = Url::fromRoute('system_test.page_cache_accept_header', ['_format' => 'json']); + $accept_header_cache_url_with_ajax = Url::fromRoute('system_test.page_cache_accept_header', ['_format' => 'json'], ['query' => ['_wrapper_format' => 'drupal_ajax']]); $this->drupalGet($accept_header_cache_url); // Verify that HTML page was not yet cached. @@ -145,6 +146,15 @@ public function testQueryParameterFormatRequests() { $this->assertSession()->responseHeaderEquals('X-Drupal-Cache', 'HIT'); // Verify that the correct JSON response was returned. $this->assertSession()->responseContains('{"content":"oh hai this is json"}'); + + $this->drupalGet($accept_header_cache_url_with_ajax); + // Verify that AJAX response was not yet cached. + $this->assertSession()->responseHeaderEquals('X-Drupal-Cache', 'MISS'); + $this->drupalGet($accept_header_cache_url_with_ajax); + // Verify that AJAX response was cached. + $this->assertSession()->responseHeaderEquals('X-Drupal-Cache', 'HIT'); + // Verify that the correct AJAX response was returned. + $this->assertSession()->responseContains('{"content":"oh hai this is ajax"}'); } /** diff --git a/core/modules/system/tests/modules/system_test/src/Controller/PageCacheAcceptHeaderController.php b/core/modules/system/tests/modules/system_test/src/Controller/PageCacheAcceptHeaderController.php index 7401f814000cab86a5bac58a4814dd326489fd6d..07418c65a67a02179f582c5a9cbdf53075b5d9ed 100644 --- a/core/modules/system/tests/modules/system_test/src/Controller/PageCacheAcceptHeaderController.php +++ b/core/modules/system/tests/modules/system_test/src/Controller/PageCacheAcceptHeaderController.php @@ -2,7 +2,9 @@ namespace Drupal\system_test\Controller; +use Drupal\Core\Cache\CacheableAjaxResponse; use Drupal\Core\Cache\CacheableJsonResponse; +use Drupal\Core\Cache\CacheableMetadata; use Drupal\Core\Cache\CacheableResponse; use Symfony\Component\HttpFoundation\Request; @@ -20,12 +22,17 @@ class PageCacheAcceptHeaderController { * @return mixed */ public function content(Request $request) { - if ($request->getRequestFormat() === 'json') { - return new CacheableJsonResponse(['content' => 'oh hai this is json']); + if ($request->getRequestFormat() === 'json' && $request->query->get('_wrapper_format') === 'drupal_ajax') { + $response = new CacheableAjaxResponse(['content' => 'oh hai this is ajax']); + } + elseif ($request->getRequestFormat() === 'json') { + $response = new CacheableJsonResponse(['content' => 'oh hai this is json']); } else { - return new CacheableResponse("<p>oh hai this is html.</p>"); + $response = new CacheableResponse("<p>oh hai this is html.</p>"); } + $response->addCacheableDependency((new CacheableMetadata())->addCacheContexts(['url.query_args:_wrapper_format'])); + return $response; } }