runtimeZero
runtimeZero

Reputation: 28046

Getting express server to accept CORS request

I have my express server running on http://localhost:3000 (I call this web-server) I have another application running on localhost:8100 (I call this simply 'app')

When my app makes a call to the webserver I receive the message:

"XMLHTTPReqeust cannot load http://localhost:3000/auth/facebook. Response to preflight request doesn't pass access control check. A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' when the credentials flag is true. Origin 'http://localhost:81000' is therefore not allowed acecss"

This message shows up in the browser console.

I have setup the following options in the middleware of my node webserver

res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT, POST,DELETE');

After reading few stackoverfow questions, I also added the following:

 res.header('Access-Control-Allow-Origin', 'http://localhost:8100');

however this does not resolve the issue.

Upvotes: 31

Views: 49169

Answers (7)

Felippe Regazio
Felippe Regazio

Reputation: 389

You must take in consideration your preflight request also. I suggest you to add the "cors" npm package on your project, and start it with this following configurations:

const cors = require('cors');

app.use(cors({
    credentials: true,
    preflightContinue: true,
    methods: ['GET', 'POST', 'PUT', 'PATCH' , 'DELETE', 'OPTIONS'],
    origin: true
}));

This will enable Cross Origin Requests for any address with the listed methods. The origin parameter is very flexible, you can delimiter a set of address, all address or by regex, for example. Here is the package docs:

https://expressjs.com/en/resources/middleware/cors.html

Upvotes: 1

Louie Almeda
Louie Almeda

Reputation: 5612

I had the same problem and stumbled for about an hour. The solution was actually simple--just enable CORS for preflight operations.

app.options('*', cors()); // include before other routes

Upvotes: 8

Thierry
Thierry

Reputation: 6457

I thought I'd had cracked this one before but once I swapped back from IIS to IIS Express, I started to get the error again!!

Started to Google once again and tried numerous suggestions, including the ones above but none of them worked until I found this article from Melvin's Web Stuff - Enable CORS IIS Express which suggested the following:

Add the following 2 lines to the <customHeaders> section under the <httpProtocol> section:

<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />

to the applicationhost.config located in:

%HOMEPATH%\Documents\IISExpress\config

The final result should look like this:

<httpProtocol>
   <customHeaders>
      <clear />
         <add name="X-Powered-By" value="ASP.NET" />
         <add name="Access-Control-Allow-Origin" value="*" />
         <add name="Access-Control-Allow-Headers" value="Content-Type" />   
   </customHeaders>
   <redirectHeaders>
      <clear />
   </redirectHeaders>
</httpProtocol>

This worked nicely for me but note that I didn't need the above when running in IIS.

Upvotes: 0

I use cors and implement it so, it's very simple

var cors=require('cors');

app.use(cors({origin:true,credentials: true}));

Upvotes: 32

runtimeZero
runtimeZero

Reputation: 28046

Apparently cors module didn't work.

Using the hints given above I used the following code:

  if (req.method === "OPTIONS") {
    res.header('Access-Control-Allow-Origin', req.headers.origin);
  } else {
    res.header('Access-Control-Allow-Origin', '*');
  }

This did the trick.

Upvotes: 12

Vsevolod Goloviznin
Vsevolod Goloviznin

Reputation: 12324

You also need to allow OPTIONS method in the header.

I have this middleware for cors:

module.exports = function (req, res, next) {
    // CORS headers
    res.header("Access-Control-Allow-Origin", "YOUR_URL"); // restrict it to the required domain
    res.header("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,OPTIONS");
    // Set custom headers for CORS
    res.header("Access-Control-Allow-Headers", "Content-type,Accept,X-Custom-Header");

    if (req.method === "OPTIONS") {
        return res.status(200).end();
    }

    return next();
};

PS. The error you get is due to the fact of how cross-origin request works. To make a long story short, the browser might first send a pre-flight request with method OPTIONS to get allowed origins, headers and methods. So for this request you should return nothing but the Access-Control-* headers. If the pre-flight went fine, the browser will continue with the original request.

You can find more information here.

Upvotes: 29

Thomas Bormans
Thomas Bormans

Reputation: 5354

I personally prefer the cors module. The code is really simple:

var whitelist = [
    'http://0.0.0.0:3000',
];
var corsOptions = {
    origin: function(origin, callback){
        var originIsWhitelisted = whitelist.indexOf(origin) !== -1;
        callback(null, originIsWhitelisted);
    },
    credentials: true
};
app.use(cors(corsOptions));

Upvotes: 24

Related Questions