Why doesn't adding CORS headers to an OPTIONS route allow browsers to access my API?

Solution 1:

I found the easiest way is to use the node.js package cors. The simplest usage is:

var cors = require('cors')

var app = express()
app.use(cors())

There are, of course many ways to configure the behaviour to your needs; the page linked above shows a number of examples.

Solution 2:

Try passing control to the next matching route. If Express is matching app.get route first, then it won't continue onto the options route unless you do this (note use of next):

app.get('somethingelse', function(req, res, next) {
    //..set headers etc.

    next();
});

In terms of organising the CORS stuff, I put it in a middleware which is working well for me:

//CORS middleware
var allowCrossDomain = function(req, res, next) {
    res.header('Access-Control-Allow-Origin', 'example.com');
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
    res.header('Access-Control-Allow-Headers', 'Content-Type');

    next();
}

//...
app.configure(function() {
    app.use(express.bodyParser());
    app.use(express.cookieParser());
    app.use(express.session({ secret: 'cool beans' }));
    app.use(express.methodOverride());
    app.use(allowCrossDomain);
    app.use(app.router);
    app.use(express.static(__dirname + '/public'));
});