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.

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 to localhost: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

  1. Upon clicking the button
  2. Makes an AJAX GET request to http://aem-publish.local/content/we-retail/.../experience/_jcr_content.1.json
  3. Retrieves the jcr:title form the JSON response
  4. 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

To allow the caching and serving of CORS headers on cached content, add following /clientheaders configuration to all supporting AEM Publish dispatcher.any files.

/myfarm {
  ...
  /clientheaders {
      "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 /clientheaders configuration update.

Supporting materials

On this page