Cross-domain Node.js Function Calls

Cross DomainNode.js and AJAX provide a full spectrum of development capabilities that rival the desktop environment. From image editing software to 3D interactive games, many desktop apps have successfully moved from the local machine to the browser. When programming these applications, however, developers often need to work around browser security restrictions, the most frequently encountered limitation being cross-domain function call prevention.

Cross-domain calls are used primarily when a script running on one domain, such as apHarmony.com, may need to request another website, such as Google.com, to perform an action. In the past, cross-domain calls were allowed by all browsers. Unfortunately, with the increased sophistication of hackers, many browsers blocked cross-domain function calls since they were easily exploited by hackers to steal user passwords and personal information.

Before understanding how to work around cross-domain function call limitations, it’s important to understand the nature of how the calls are blocked in a browser. Many web pages have dynamic components that are populated by user inputs. For instance, a web page might ask for a user’s name, and then display that user name on a subsequent page. If a hacker injects HTML into that field instead of regular text, the website will embed that HTML into other pages of the site, enabling the hacker to take control of all the elements on the page.

Since a large number of sites were subject to this vulnerability, most popular browsers (Internet Explorer, Google Chrome, Mozilla Firefox, and Safari) have blocked this capability. Websites loaded in an IFRAME are generally blocked from accessing the parent window, if the website is on a different domain from the parent. The error displayed by the browser is often “Domains, protocols and ports must match”. The workaround to this is using a technology called JSONP.

JSONP, instead of embedded the target website using an IFRAME, embeds the target site using a SCRIPT tag. The SCRIPT method is still supported by most browsers, and used by the majority of plugins, such as Google Analytics. JSONP loads a SCRIPT resource dynamically, and calls a function on the parent page once the SCRIPT has completed loading. The workflow is as follows:

1. Assuming a page on apHarmony.com wants to access the “getTime” function on Google.com

2. The apHarmony.com page will have a callback defined:
function getTimeComplete(data) { alert(data.strTime); }
3. When a button is pressed on the apHarmony.com site, JavaScript will add the following text to the page using document.write:
document.write('<script type="text/javascript" src="//www.google.com/getTime?callback=getTimeComplete&timestamp=1349023490"></script>');
4. The browser will access the dynamic page on Google, and Google will reply with the following HTML embedded back into the apHarmony.com page:
getTimeComplete({strTime:'7/26/2015 2:13pm'});
5. The apHarmony page will then execute the getTimeComplete callback, processing the result and displaying it to the user.

The key to this technology is the use of a dynamic callback function – allowing the client page (apHarmony.com) to define any callback function for the request to the server. This enables the JSONP web service to be integrated into any JavaScript application.

The jQuery toolkit takes this one step further, by automatically handling the callback creation. The sample code for integrating cross-domain JSONP calls with Node.js is as follows:

Client JavaScript:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
  var url = 'http://localhost:3000/getTime';
  $.ajax({
    url: url,
    jsonp: 'callback',
    dataType: 'jsonp',
    complete: function (data) {
      var rslt = data.responseJSON;
      alert(rslt.strTime);
    }
  });
});
</script>

Server Route:

router.get('/getTime', function(req, res) {
  var rslt = { 'strTime': (new Date()).toString() };
  res.end(req.query.callback+'('+JSON.stringify(rslt)+');');
});

Written by Andrew Palczewski

About the Author
Andrew Palczewski is CEO of apHarmony, a Chicago software development company. He holds a Master's degree in Computer Engineering from the University of Illinois at Urbana-Champaign and has over ten years' experience in managing development of software projects.
Google+

RSS Twitter LinkedIn Facebook Email

Leave a Reply

Your email address will not be published. Required fields are marked *