Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2 to REST WebApi CORS issue

I'm using an angular2 front end and WebApi backend. The webapi is CORS enabled

var cors = new EnableCorsAttribute("*", "*", "*");
GlobalConfiguration.Configuration.EnableCors(cors);

and it works, because I have different sites (jQuery/Javascript) that use this api. But with angular2 it doesn't. I get the following message:

Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Maybe is something related to "preflight request" ?

like image 473
Marcos Avatar asked Feb 04 '16 13:02

Marcos


2 Answers

I had the same issue in my Angular2 application. The problem, as already stated, is that before every request made by the client a preflight request is sent to the server.

This kind of request have a type OPTIONS, and it's duty of the server to send back a preflight response with status 200 and headers set for accepting requests from that client.

This is my solution (with express):

// Domain you wish to allow
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');

// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');

// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'YOUR-CUSTOM-HEADERS-HERE');

// Set to true if you need the website to include cookies in  requests
res.setHeader('Access-Control-Allow-Credentials', true);

// Check if preflight request
if (req.method === 'OPTIONS') {
    res.status(200);
    res.end();
}
else {
    // Pass to next layer of middleware
    next();
}

As you can see, i set the headers and then fetch if the request type is OPTIONS. In that case i send back a status 200 and end the response.

In this way, the client will be authorized and you will be also able to set your custom headers in all the requests.

like image 179
Matteo Tosi Avatar answered Sep 28 '22 18:09

Matteo Tosi


Your error message tells that there is no Access-Control-Allow-Origin in the response of your call. It's something necessary to enable CORS for this request. It's not something related to Angular2.

This is triggered on the client side by the adding of the Origin header in the request. Do you have this header in your request? Do you use preflighted requests in your other applications. As a reminder:

  • Simple requests. This use case applies if we use HTTP GET, HEAD and POST methods. In the case of POST methods, only content types with the following values are supported: text/plain, application/x-www-form-urlencoded and multipart/form-data.
  • Preflighted requests. When the "simple requests" use case doesn't apply, a first request (with the HTTP OPTIONS method) is made to check what can be done in the context of cross-domain requests.

Perhaps OPTIONS requests aren't correctly handled on the server side (don't return correct headers, ...).

What would be interested is to tell us on which requests the error occurs: the OPTIONS one or the target request. You can have a look at the Network tab in DevTools...

See these links for more details about how CORS works:

  • http://restlet.com/blog/2015/12/15/understanding-and-using-cors/
  • http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api#enable-cors

Hope it helps you, Thierry

like image 36
Thierry Templier Avatar answered Sep 28 '22 17:09

Thierry Templier