I have recently wrote a JavaScript web application that depended on AJAX and a Java driven back end. The back end was a standard RESTful Web service running an a Glassfish server. Before I started working on the application a designer was hired to make the HTML/CSS layout that was desired. As I got further into the development process and the moving parts started to change the CSS also needed to change. This proposed a problem for us mainly because all of the data ( and the html elements needed to display it) that were needed to populate each page had to be requested from the Web service. Typically what I would do is log in to the web application running on the test server fired up firebug and use the HTML/CSS edit feature to get the CSS to where I needed it to be. Alternatively, I would save the website and open the HTML and CSS pages locally and edit from there. Any CSS changes would then get committed to the repo. However, this wasn’t a good enough way for the designer. The designer wanted to put the repo on their localhost and simply run the application on their local server. This of course caused a CORS error because an XHR request could not be made from localhost to a remote server.
To solve this problem the designer could have got a local copy of the back end working on his localhost as well. However that would involve mysql, eclipse and glassfish to be configured correctly. Not really ideal. So I went out in search for another solution. After talking to some people I decided to use node.js. Havent yet worked with node I wasn’t quite sure of what I was going to do. Some people said i needed a Proxy some said i needed Middleware but at the end of it all I just needed a simple server and a client.
The Structure
The idea is for a server to listen to the requests coming in from your localhost on a particular port. This means that the URL of the XHR requests has to be changed to localhost:portnumber. Once the request is captured, a dummy client will make the same exact request but instead of the client being your localhost, it will be a node client whose domain is the same as the domain of the back end. Create a client using the domain of the back end. I never really found any documentation of what the createClient function accepted so let me show you what I used:
var aclient = http.createClient(80, 'backendurl.com');
The next step is to create a server that listens on a particular port. This is the same port i mentioned above. Ensure that this port is not being used by another application running on your computer otherwise you will get a weird port not available exception. Now, in the function that you pass in when you create the server you need to capture the request, get the needed data and make a similar request with a new url. You also need to figure out what the request method is. This is important because sometimes there will be an OPTIONS method sent which is basically a way of the browser testing if CORS is allowed.
if (req.method === 'OPTIONS') { // add needed headers var headers = {}; headers["Access-Control-Allow-Origin"] = "*"; headers["Access-Control-Allow-Methods"] = "POST, GET, PUT, DELETE, OPTIONS"; headers["Access-Control-Allow-Credentials"] = true; headers["Access-Control-Max-Age"] = '86400'; // 24 hours headers["Access-Control-Allow-Headers"] = "X-Requested-With, Access-Control-Allow-Origin, X-HTTP-Method-Override, Content-Type, Authorization, Accept"; // respond to the request res.writeHead(200, headers); res.end(); } else if (req.method === 'GET') { // no data is coming // use the client you created to make a request, this request will basically // need all of the information captured in this GET request coming from your localhost:portnumber var clientrequest = aclient.request(req.method, '/api' + req.url, { 'host': 'backendurl.com', 'authorization': req.headers['authorization'], 'content-type': 'application/json', 'connection': 'keep-alive', }); clientrequest.end(); var msg = "", clietheaders; // get the response from the back-end clientrequest.on('response', function (clientresponse) { clientheaders = clientresponse.headers; clientresponse.on('data', function (chunk) { msg += chunk; }); }); setTimeout(function () { // send the data you just received from the back end back to you // client application on localhost res.writeHead(200, clientheaders); res.write(msg); res.end(); }, 500); // wait a bit just in case we don't have all of the chunks of data }