Develop for Cross-Origin Resource Sharing (CORS)
A short example of leveraging CORS to access AEM content from an external web application via client-side JavaScript. This example uses the CORS OSGi configuration to enable CORS access on AEM. The OSGi configuration approach is viable when:
- A single origin is accessing AEM Publish content
- CORS access is required for AEM Author
If multi-origin access to AEM Publish is required, refer to this documenation.
In this video:
- www.example.com maps to localhost via
/etc/hosts
- aem-publish.local maps to localhost via
/etc/hosts
- SimpleHTTPServer (a wrapper for Python’s SimpleHTTPServer) is serving the HTML page via port 8000.
- No longer available in Mac App Store. Use similar such as Jeeves.
- AEM Dispatcher is running on Apache HTTP Web Server 2.4 and reverse-proxying request to
aem-publish.local
tolocalhost:4503
.
For more details, review Understanding Cross-Origin Resource Sharing (CORS) in AEM.
www.example.com HTML and JavaScript
This Web page has logic that
- Upon clicking the button
- Makes an AJAX GET request to
http://aem-publish.local/content/we-retail/.../experience/_jcr_content.1.json
- Retrieves the
jcr:title
form the JSON response - Injects the
jcr:title
into the DOM
<html>
<head>
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
</head>
<body style="width: 960px; margin: 2rem auto; font-size: 2rem;">
<button style="font-size: 2rem;"
data="fn-getTitle">Get Title as JSON from AEM</button>
<pre id="title">The page title AJAX'd in from AEM will injected here</pre>
<script>
$(function() {
/** Get Title as JSON **/
$('body').on('click', '[data="fn-getTitle"]', function(e) {
$.get('http://aem-publish.local/content/we-retail/us/en/experience/_jcr_content.1.json', function(data) {
$('#title').text(data['jcr:title']);
},'json');
e.preventDefault();
return false;
});
});
</script>
</body>
</html>
OSGi factory configuration
The OSGi Configuration factory for Cross-Origin Resource Sharing is available via:
http://<host>:<port>/system/console/configMgr > Adobe Granite Cross-Origin Resource Sharing Policy
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="sling:OsgiConfig"
alloworigin="[https://www.example.com:8000]"
alloworiginregexp="[]"
allowedpaths="[/content/we-retail/.*]"
exposedheaders="[]"
maxage="{Long}1800"
supportedheaders="[Origin,Accept,X-Requested-With,Content-Type,
Access-Control-Request-Method,Access-Control-Request-Headers]"
supportedmethods="[GET]"
supportscredentials="{Boolean}false"
/>
Dispatcher configuration dispatcher-configuration
Allowing CORS request headers
To allow the required HTTP request headers to passthrough to AEM for processing, they must be allowed in the Disaptcher’s /clientheaders
configuration.
/clientheaders {
...
"Origin"
"Access-Control-Request-Method"
"Access-Control-Request-Headers"
}
Caching CORS resposne headers
To allow the caching and serving of CORS headers on cached content, add following /cache /headers configuration to the AEM Publish dispatcher.any
file.
/publishfarm {
...
/cache {
...
# CORS HTTP response headers
# https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#the_http_response_headers
/headers {
...
"Access-Control-Allow-Origin"
"Access-Control-Expose-Headers"
"Access-Control-Max-Age"
"Access-Control-Allow-Credentials"
"Access-Control-Allow-Methods"
"Access-Control-Allow-Headers"
}
...
}
...
}
Restart the web server application after making changes to the dispatcher.any
file.
It is likely clearing the cache entirely is required to ensure headers are appropriately cached on the next request after a /cache /headers
configuration update.