Cross-Origin Resource Sharing (CORS) with a Node.JS Express.JS and Sencha Touch app

Many times, especially during the development process you will be building an application with a team of several developers. To facilitate the development process there may be times where you may in charge of building either the server side resources, and another developer is in charge of building the UI piece or vice-versa.

Both the Sencha Touch and ExtJS frameworks will recognize that a Cross-Origin conflict is occurring during an AJAX request and automatically use what is called a preflight mechanism to determine if the resources can be utilized.

What’s going on here?

The browser has a mechanism to prevent Cross-site scripting by looking at the origin of a request with the resource the javascript is requesting. For instance, this happens when you are developing your Sencha touch or ExtJS application using http://localhost:3000 as your development platform, but requesting resources from a different URL such as http://localhost:3001 or http://thedevelopmentboxurl.com

Here’s what you will see in the debugger console:

cors_error

Luckily, Sencha uses a preflight mechanism as specified in the CORS specification to determine if the resources can be utilized. The preflight process simply issues an OPTIONS request to the server and looks at the headers which are returned.

There are many ways to address this issue during Sencha Touch or ExtJS development (or production if you wanted).

If I was building a node.js application using express I can simply add some middleware to look for the OPTIONS request and add the appropriate Header information to send back to the client:

app.js

// Enables CORS
var enableCORS = function(req, res, next) {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
    res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');

    // intercept OPTIONS method
    if ('OPTIONS' == req.method) {
      res.send(200);
    }
    else {
      next();
    }
};


// enable CORS!
app.use(enableCORS);
//--------------

The key headers are: Access-Control-Allow-Origin, Access-Control-Allow-Methods and Access-Control-Allow-Headers

I had to made no changes to the Sencha side of the house. Everything was implemented for me! Groovy! This is definitely a lot easier then worrying about JSONP.

If I was using a different technology stack, but using nginx, I could simply add an entry into my nginx.conf file as found in this configuration example.

Conclusion

This is a pretty simple concept, but definitely worthwhile demonstrating. Life is simple when you are developing both server and client code on the same machine, but in larger teams you are likely going to need this sort of setup. I hope this helps you out in your development activities!

Resources

http://enable-cors.org/index.html

https://developer.mozilla.org/en/docs/HTTP/Access_control_CORS

Google+