Allow CORS REST request to a Express/Node.js application on Heroku

Jamie Folsom picture Jamie Folsom · Jun 12, 2012 · Viewed 75.7k times · Source

I've written a REST API on the express framework for node.js that works for requests from the js console in Chrome, and URL bar, etc. I'm now trying to get it working for requests from another app, on a different domain (CORS).

The first request, made automatically by the javascript front end, is to /api/search?uri=, and appears to be failing on the "preflight" OPTIONS request.

In my express app, I am adding CORS headers, using:

var allowCrossDomain = 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();
    }
};

and:

app.configure(function () {
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(app.router);
  app.use(allowCrossDomain);
  app.use(express.static(path.join(application_root, "public")));
  app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});

From the Chrome console I get these headers:

Request URL:http://furious-night-5419.herokuapp.com/api/search?uri=http%3A%2F%2Flocalhost%3A5000%2Fcollections%2F1%2Fdocuments%2F1

Request Method:OPTIONS

Status Code:200 OK

Request Headers

Accept:*/*
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:origin, x-annotator-auth-token, accept
Access-Control-Request-Method:GET
Connection:keep-alive
Host:furious-night-5419.herokuapp.com
Origin:http://localhost:5000
Referer:http://localhost:5000/collections/1/documents/1
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.56 Safari/536.5

Query String Parameters

uri:http://localhost:5000/collections/1/documents/1

Response Headers

Allow:GET
Connection:keep-alive
Content-Length:3
Content-Type:text/html; charset=utf-8
X-Powered-By:Express

Does this look like a lack of proper headers being sent by the API application?

Thanks.

Answer

Olegas picture Olegas · Jun 15, 2012

I've cheked your code on a clean ExpressJS app and it works just fine.

Try move your app.use(allowCrossDomain) to the top of configure function.