AngularJS $resource makes HTTP OPTIONS request instead of HTTP POST for $save method AngularJS $resource makes HTTP OPTIONS request instead of HTTP POST for $save method express express

AngularJS $resource makes HTTP OPTIONS request instead of HTTP POST for $save method


I know it may be in bad taste to answer my own question but I figured out the problem a few days after posting this.

It all comes down to how browsers manage CORS. When making a cross-domain request in JavaScript that is not "simple" (i.e. a GET request - which explains why the query() function worked), the browser will automatically make a HTTP OPTIONS request to the specified URL/URI, called a "pre-flight" request or "promise". As long as the remote source returns a HTTP status code of 200 and relevant details about what it will accept in the response headers, then the browser will go ahead with the original JavaScript call.

Here's a brief jQuery example:

function makeRequest() {    // browser makes HTTP OPTIONS request to www.myotherwebsite.com/api/test    // and if it receives a HTTP status code of 200 and relevant details about    // what it will accept in HTTP headers, then it will make this POST request...    $.post( "www.myotherwebsite.com/api/test", function(data) {        alert(data);    });    // ...if not then it won't - it's that simple.}

All I had to do was add the details of what the server will accept in the response headers:

// apply this rule to all requests accessing any URL/URIapp.all('*', function(req, res, next) {    // add details of what is allowed in HTTP request headers to the response headers    res.header('Access-Control-Allow-Origin', req.headers.origin);    res.header('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS');    res.header('Access-Control-Allow-Credentials', false);    res.header('Access-Control-Max-Age', '86400');    res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept');    // the next() function continues execution and will move onto the requested URL/URI    next();});

And then insert these few lines before the Express routing to simply return a HTTP 200 status code for every OPTIONS request:

// fulfils pre-flight/promise requestapp.options('*', function(req, res) {    res.send(200);});

Hopefully this will help anyone who stumbles on this page suffering from the same problem.


I didn´t actually try this, but wouldn´t it be enough to tell the Ressource how to handle the $save request?

$resource('http://mywebserver\\:1337/books/:bookId', { bookId: '@bookId' }, {save: {method: 'POST'});