2

I currently have a NodeJS + ExpressJS as a client-server making API requests to a back-end server. When I make an API request, I get the following error:

Request header field firstname is not allowed by Access-Control-Allow-Headers in preflight response.

I tried everything to allow CORS but I am still getting the same error. Here is how my NodeJS + ExpressJS client-server is set up as:

    var express = require('express');
    var cors = require('cors');
    var path = require('path');
    var config = require('../webpack.config.js');
    var webpack = require('webpack');
    var webpackDevMiddleware = require('webpack-dev-middleware');
    var webpackHotMiddleware = require('webpack-hot-middleware');
    var app = express();
    var compiler = webpack(config);
    
    app.use(cors());
    
    app.use(webpackDevMiddleware(compiler, {noInfo: true, publicPath: config.output.publicPath}));
    
    app.use(webpackHotMiddleware(compiler));
    
    app.use(express.static('./dist'));
    
    app.use('/', function (req, res) {
      res.header("Access-Control-Allow-Origin", "*");
      res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
      res.sendFile(path.resolve('client/index.html'))
    })
    
    var port = 3000;
    
    app.listen(port, function(error) {
      if (error) throw error;
      console.log("Express server listening on port", port);
    });

What may be the issue? The only way that currently works is by downloading https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?hl=en and enabling it, then I would not get the error and API request would be successful.

EDIT - How I am making the API request

  logInUser(userCredentials) {

    var userCredsBody = {
        'firstname': `${userCredentials.username}`,
        'password': `${userCredentials.password}`
    }

    var configuration = {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(userCredsBody)
    }

    return function(dispatch) {
      fetch('https://serverapi.com:8080/userInfo', configuration)
      .then(response => response.json())
      .then(response => {
        console.log('Successful and ', response)
      })
      .catch((error) => {
        console.log("Error: ", error)
      })
    }
Jo Ko
  • 7,225
  • 15
  • 62
  • 120

1 Answers1

4

Change the headers order.

Use something like this:

var express = require('express');
//This is not longer required, unless you want to disable CORS
//var cors = require('cors');
var path = require('path');
var bodyParser = require('body-parser');
var config = require('../webpack.config.js');
var webpack = require('webpack');
var webpackDevMiddleware = require('webpack-dev-middleware');
var webpackHotMiddleware = require('webpack-hot-middleware');
var app = express();
var compiler = webpack(config);
//The same, no longer required
//app.use(cors());

app.use(webpackDevMiddleware(compiler, {noInfo: true, publicPath: config.output.publicPath}));

app.use(webpackHotMiddleware(compiler));

app.use(express.static('./dist'));
//Add bodyParser to parse all body as JSON
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));

function setupCORS(req, res, next) {
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
    res.header('Access-Control-Allow-Headers', 'X-Requested-With, Content-type,Accept,X-Access-Token,X-Key');
    res.header('Access-Control-Allow-Origin', '*');
    if (req.method === 'OPTIONS') {
        res.status(200).end();
    } else {
        next();
    }
}
app.all('/*', setupCORS);

app.use('/', function (req, res) {
    res.sendFile(path.resolve('client/index.html'))
});

var port = 3000;

app.listen(port, function(error) {
    if (error) throw error;
    console.log("Express server listening on port", port);
});

Now you have a middleware setting CORS to each request.

If you want to disable/enable cors, on a single route, perhaps you need to change the

app.all('/*', setupCORS);

to only the routes you want to setup with a CORS configuration.

I added a body-parser middleware.

manuerumx
  • 1,230
  • 14
  • 28
  • Sorry but before I accept the answer and upvote, could you show the full code along with mine? Am aware the sequence is important, so want to make sure that I have them set up in the proper order – Jo Ko Oct 12 '16 at 00:53
  • @JoKo I made and edit and include all the code. The setupCORS should be included **before** the routes – manuerumx Oct 12 '16 at 01:02
  • By the way, unless you want a more strict control over the routes and responses in your app, you should avoid my method and check the CORS module configuration. I like my function, because is easy to implement and has no external dependencies. – manuerumx Oct 12 '16 at 01:09
  • @Appreciate the update and I gave it an attempt, but I am still getting the error: `Fetch API cannot load https://serverapi.com:8080/userInfo. Request header field userfirstname is not allowed by Access-Control-Allow-Headers in preflight response.` and `Error: TypeError: Failed to fetch(…)`. And for clarification, `https://serverapi.com:8080` is the back-end API server URL. – Jo Ko Oct 12 '16 at 01:35
  • @JoKo how are you making the request? Perhaps the problem is the content-type. Are you using angular or jquery? Look this response: http://stackoverflow.com/a/30554385/1757214 – manuerumx Oct 12 '16 at 01:50
  • Ohhh change app.use for : app.get('/', function (req, res) { res.sendFile(path.resolve('client/index.html')) }); – manuerumx Oct 12 '16 at 01:51
  • Just gave app.use a try and still getting the same error. Please take a look at the original post, I updated with how I make my request. When I use the Chrome extension to enable CORS, the API call is successful. – Jo Ko Oct 12 '16 at 01:57
  • Sorry I meant I gave app.get a try and is still a no go. – Jo Ko Oct 12 '16 at 02:04
  • Just checking in to see if you've seen my last comment. Please let me know – Jo Ko Oct 12 '16 at 05:52
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/125517/discussion-between-manuerumx-and-jo-ko). – manuerumx Oct 12 '16 at 14:40
  • Just saw the comment and entered the chat. Please let me know when you become available. Thanks – Jo Ko Oct 12 '16 at 19:57