Cross Domain Access to DTS with EasyXDM

One common challenge that web developers face involves cross domain AJAX requests when servers settings are not configured to allow AJAX requests. Percussion leverages the easyXDM library to enable cross-domain AJAX requests to DTS resources that are not running on the same server hosting the website.

EasyXDM is a Javascript library that enables you as a developer to easily work around the limitation set in place by the web browser’s default Same Origin Policy, in turn making it easy to communicate and expose javascript API’s across domain boundaries. - "http://easyxdm.net/"

This documentation is separated in two parts:

  • Part I: Using Percussion Service Utility JavaScript API from Percussion sites

This example is useful when your code is running on pages published by Percussion but where your DTS server and web server are on separate machines running behind separate domains or subdomains.  

  • Part II: Reaching the Percussion DTS Metadata Service from non-Percussion sites

This example is useful when you have code running on web pages that are not published by Percussion and do not have access to the Percussion Service Utility JavaScript library that publishes with Percussion pages. 


Part I: Using Percussion Service Utility JavaScript API from Percussion sites

Percussion's JavaScript API exposes two methods that lean on easyXDM:

  • makeXdmXmlRequest
  • makeXdmJsonRequest

makeXdmXmlRequest

This method is used for requesting XML content and is used by Percussion to retrieve RSS feeds for the RSS widget. Documentation for this method will follow at a later date.

makeXdmJsonRequest

This method is much more frequently used by Percussion widgets for retrieving content from the Percussion DTS metadata service which responds with JSON data.

The method syntax and arguments are as follows:

$.PercServiceUtils.makeXdmJsonRequest(servicebase, url, type, callback, dataObject);

Method Arguments:

servicebase

This argument can be used to override the default DeliveryService URL if required. If left as null then this argument will be set to the delivery service property value configured in Percussion/rxconfig/DeliveryServer/delivery-servers.xml.

With Percussion widgets, this is commonly set to null.

url

This URL should point to one of the DTS metadata service API endpoints. For example, this could be set to the combination of: jQuery.getDeliveryServiceBase + "/perc-metadata-services/metadata/get"

type

This argument support two types of AJAX values: GET and POST and must be entered as: $.PercServiceUtils.TYPE_POST or $.PercServiceUtils.TYPE_GET

callback

The callback argument is where one can specify the logic to be performed after the AJAX response is returned and receive two parameters commonly set to status and results.

dataObject

The dataObject is where one can optionally set the Payload JSON data to pass along with a POST request.

Example usage:

The Percusion Blog widget, for example, uses the makeXdmJsonRequest like

$(document).ready(function() {

// Here we can configure a simple AJAX POST payload object for requesting 5 pages orders by most recent publish date.

var queryString = {

   "criteria":[

       "type = 'page'"

   ],

   "maxResults": 5,

   "orderBy": "dcterms:created desc",

   "startIndex": 1

}

function handleResponse(status, results) {

   if(status == $.PercServiceUtils.STATUS_SUCCESS){

       // If successfull we can log the response along with a success message.

       console.log("Hello World!");

       console.log("Look at my Percussion pages!");

       console.log(results.data.results);

   }

   else{

       var defMsg = $.PercServiceUtils.extractDefaultErrorMessage(results.request);

       // If the response is unsuccessful then we can log the error message for debugging

       console.log("AJAX query unsuccessful.");

       console.log(defMsg);

   }

}

   // Here we define our example function with arguments expecting a queryString POST payload

   // and our callback function to process the response of the AJAX request

function sampleXdmJsonRequest(queryString, callback) {

   // Here we set the serviceUrl to the Percussion DTS page API endpoint

   var serviceUrl = "/perc-metadata-services/metadata/get";

   // Here we call the akeXdmJsonRequest method with the following arguments:

      // The servicebase parameter is set to `null` if using the Delivery Service URL parameter assigned through the delivery-servers.xml configuration file.

      // The service URL for the DTS endpoint is used next.

      // The AJAX type is set to POST.

      //  Then we pass in our callback function (which is handleResponse) to either perform logic on success or render and error message.

      // Last we pass in our quesryString parameter with our AJAX Post payload object.

   

   $.PercServiceUtils.makeXdmJsonRequest(null, serviceUrl, $.PercServiceUtils.TYPE_POST, callback, queryString);

}

// With our functions and variables defined above here we can call the function passing it our queryString POST payload and the callback function.

sampleXdmJsonRequest(queryString, handleResponse);

});  

This example code snippet can be used in an HTML widget, then published and inspected in your browser developer tools console to view the response of the AJAX request.


Part II: Reaching the Percussion DTS Metadata Service from non-Percussion sites

You can download a zip file with the following example to test and modify for your own projects.

Click here to download.

In order to reach the Percussion Metadata Service from non-Percussion pages we don’t have the Percussion Service Utility JavaScript API to rely on, but we can still leverage easyXDM to make the Cross Domain request safely. We just need to modify our JavaScript file somewhat.

First we need to supply a couple dependencies: EasyXDM and jQuery

http://easyxdm.net/wp/

https://jquery.com/download/

Once we have these downloaded we can test our example using an HTML file on a web server, even a localhost server and include our javascript file references.

<html>

   <head>

       <script type="text/javascript" src="/js/jquery-1.7.2.js"></script>

       <script type="text/javascript" src="/js/easyXDM.js"></script>

       <script type="text/javascript" src="/js/easyXDM-example.js"></script>

   </head>

   <body>

       <h1>EasyXDM Example Application</h1>

       <div>AJAX call to Cross Domain Percussion DTS</div>

       <div>

           <div>Response:</div>

           <div id="response"></div>

       </div>

   </body>

</html>

In our example we’re also referencing an easyXDM-example.js script. Since this page will be running outside of a Percussion site, we won’t have access to the PercServiceUtils JavaScript library, so instead of calling $.PercServiceUtils.makeXdmJsonRequest we can define our own makeXdmJsonRequest function in the script below:

$(document).ready(function() {

// Set up variables for our makeXdmJsonRequest:

// The servicebase needs to be set to the value set in the delivery-server field in <Percussion-root>/rxconfig/DeliveryServer/delivery-servers.xml

var servicebase = "http://your-delivery-server.com";

// Here we set the serviceUrl to the Percussion DTS page API endpoint

var serviceUrl = "http://your-delivery-server/perc-metadata-services/metadata/dated/get";

// The AJAX type is set to "POST"

// Here we can configure a simple AJAX POST payload object for requesting events from the main-calendar

var payload = {

   "criteria":[

       "type = 'page'"

       // enter additional page parameter values here

   ],

   "maxResults": 5,

   "startIndex": 1

}

// Then we pass in our callback function (which is handleResponse) to either perform logic on success or render and error message

function handleResponse(response) {

   console.log(response.status);

   console.log(response);

   if(response.status == 200){

       // If successful we can log the response along with a success message.

       console.log(response.data);

       $('#response').text("Response successful. See browser developer console for output.");

   }

   else{

       // If there is an error then it can be handles here with additional logic

       console.log("AJAX query unsuccessful.");

       console.log("AJAX response code: " + response.status);

   }   

}

// Call the sampleXdmJsonRequest function passing it a queryString POST payload and our callback function which will run after the AJAX request is completed.  

makeXdmJsonRequest(servicebase, serviceUrl, "POST", handleResponse, payload);

// This is the definition of our makeXdmJsonRequest function.

function makeXdmJsonRequest(servicebase, url, type, callback, dataObject){

var self = this;

if(typeof(easyXDM) == 'undefined') {

   // No easyXDM found, attempt to fallback to normal json request

   console.error("easyXDM not defined. Please update JavaScript libraries.");

}

if(callback == null || typeof(callback) == 'undefined') {

   console.error("Callback cannot be null or undefined");

   return;

}

if(!(type == "GET" || type == "POST")) {

   console.error("Invalid type specified, must be GET or POST.");

   return;    

}

if(servicebase == null || typeof(servicebase) == 'undefined') {

                console.error("ServiceBase not defined. Please point to Percussion DTS URL");

}

var rpc = new easyXDM.Rpc({

         remote: servicebase + "/perc-common-ui/cors/"

     },

     {

       remote: {

           request: {}

       }

     });

var opts = {

   url: url,

   headers: {"Content-Type": "application/json",

   "Accept": "application/json,text/plain"

    "perc-tid":tenantId,

    "perc-version":version

},

      method: type,

                 timeout: 60000

};

       

// Add payload object if it exists

if(dataObject != null && dataObject != '' && typeof(dataObject) != 'undefined')

{

opts["data"] = easyXDM.getJSONObject().stringify(dataObject);

}

   rpc.request(opts,

      function(response){ //On Success

        var isJsonResp = response.headers["Content-Type"] == "application/json";

        var resp = {

          data: isJsonResp ? JSON.parse(response.data) : response.data,

          status: response.status   

       };

       callback(resp);

      },

      function(response){ //On Error

      var resp = {

          message: response.message,

          status: response.status

      };

      callback(resp);

     });

}    // end makeXdmJsonRequest function definition

}); //end document ready

Please let us know in the comments box below if this example was helpful for you!

Happy coding!