Fix missing CORS headers for GraphQL persisted queries in AEM as a Cloud Service
This article describes how to resolve missing CORS headers on GraphQL persisted query responses in Adobe Experience Manager as a Cloud Service when CDN caching interferes. The solution involves updating cache-control headers to prevent CDN caching and ensure CORS headers are present.
Description description
Environment
- Adobe Experience Manager as a Cloud Service Publish or Preview
- GraphQL persisted-query endpoint:
/graphql/execute.json/* - Cross-origin browser access through the Adobe-managed CDN
Issue/Symptoms
- A browser reports a CORS error when a cross-origin application requests a GraphQL persisted query.
- The request includes an
Originheader, but the CDN response doesn’t include the requiredAccess-Control-Allow-Originheader. - Repeated requests from different origins receive a cached response without the required CORS header. The response headers show a cache
HITand a nonzeroAge. - Dispatcher caching for the persisted-query endpoint is disabled, but the Adobe-managed CDN still serves a cached response.
- An OSGi CORS policy is configured in AEM, but the Publish response still lacks the CORS header.
Cause
The Adobe-managed CDN cached a GraphQL persisted-query response without Access-Control-Allow-Origin and served that cached response to later requests for the same URL. Disabling Dispatcher caching doesn’t disable Adobe CDN caching. For Publish and Preview, configure CORS in the Dispatcher vhost; the Publish and Preview services don’t use the OSGi CORS policy for this configuration.
Resolution resolution
Follow the steps below to resolve the issue:
-
Review the Dispatcher configuration and verify that caching is not enabled for the GraphQL persisted query endpoint
/graphql/execute.json/*. The configuration variable that controls this behavior is typicallyCACHE_GRAPHQL_PERSISTED_QUERIES. Ensure that the variable is undefined or configured to prevent caching for this path. -
Update the Dispatcher vhost configuration to use
mod_headersand set theCache-Controlheader toprivate, no-store, no-cache, must-revalidate, max-age=0for the GraphQL persisted query endpoint.code language-none Header set Cache-Control “private, no-store, no-cache, must-revalidate, max-age=0” -
Apply the configuration changes and reload or restart the Dispatcher service.
-
Test the GraphQL persisted query endpoint by sending a request that includes an
Originheader. -
Verify that the response includes the expected
Access-Control-Allow-Originheader. -
Verify that the
x-cacheresponse header returnsMISSinstead ofHIT, confirming that the response is not being served from the CDN cache. -
Review the AEM CORS policy configuration and verify that
com.adobe.granite.cors.impl.CORSPolicyImplis configured to allow the required origins for the endpoint. -
If the CDN has already cached a response that does not include the required CORS header, purge or invalidate the cache for the affected endpoint to ensure that subsequent requests receive the correct headers.
-
Verify that requests to the GraphQL persisted query endpoint return the expected CORS headers and are processed successfully.