ShadowCore
ShadowCore

Reputation: 319

Express & Node: CORS fails

I have a Express and Node backend API written for my Angular 2 front end.

I get this common error when CORS is not set up properly in the entry file for the server:

XMLHttpRequest cannot load https://keilcarpenter-portfolioapi.herokuapp.com/api/sendemail. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://keilcarpenter.co.nz' is therefore not allowed access. The response had HTTP status code 503..

Here is the http POST request from the client:

sendEmail(queryObject: any) {
  const body = JSON.stringify(queryObject);
  const headers = new Headers();
  headers.append('Content-Type', 'application/json');
  return this.http.post('https://keilcarpenter-portfolioapi.herokuapp.com/api/sendemail', body, {headers: headers})
  .map((response: Response) => response.json());
}

The error implies that I am passing a preflight request but its only a POST request and from my understanding a request is only preflighted if it is any other than a GET, POST or HEAD request which is confirmed in this HTTP Access Control documentation

I am positive I have set my CORS headers up properly according to enable-cors.org

// Get dependencies
var express = require('express');
var path = require('path');
var http = require('http');
var bodyParser = require('body-parser');
// Get our API routes
var api = require('./server/routes/api');
var app = express();
// Parsers for POST data
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
// Point static path to dist
app.use(express.static(path.join(__dirname, 'dist')));
app.use(function (req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    next();
});
// Set our api routes
app.use('/api', api);
// Catch all other routes and return the index file
app.get('*', function (req, res) {
    res.sendFile(path.join(__dirname, 'dist/index.html'));
});
/**
 * Get port from environment and store in Express.
 */
var port = process.env.PORT || '3000';
app.set('port', port);
/**
 * Create HTTP segggrver.
 */
var server = http.createServer(app);
/**
 * Listen on provided port, on all network interfaces.
 */
server.listen(port, function () { return console.log("API running on localhost:" + port); });
//# sourceMappingURL=server

Questions

Upvotes: 0

Views: 5646

Answers (1)

sideshowbarker
sideshowbarker

Reputation: 88326

The request gets preflighted due to headers.append('Content-Type', 'application/json')

The error implies that I am passing a preflight request but its only a POST request and from my understanding a request is only preflighted if it is any other than a GET, POST or HEAD request which is confirmed in this HTTP Access Control documentation

See the part of those same docs that says this:

If the Content-Type header has a value other than the following:

  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

And you need to ensure your express code handles the OPTIONS request in the right way. For help with that, see the answer at CORS with Express.js and Angular2 or as suggested in a comment above, just use https://www.npmjs.com/package/cors, which takes care all this stuff for you.

Upvotes: 2

Related Questions