0

I am currently writing an angular app which is communicated with a server part developed with Web API 2.

Some times I want to add a specific header in the response of the query. I have enabled CORS.

When the call is made from the same origin, no problem, the value is in the response header and I can threat it in the angular side. When the call is made from another origin, the header name is not available in the response.

In both cases, when I inspect the queries through the developer tools in Chrome, I see the headers in the response.

Any idea from what I am doing wrong? Is there something special to do in the Angular part?

For test purposes, I simply do that in Web API:

public static void Register(HttpConfiguration config)
{
        var cors = new EnableCorsAttribute("*", "*", "*");
        config.EnableCors(cors);
     .....
    // rest of the implementation (Routes, etc...)
    }

UPDATE

I have written a ICorsPolicyProvider :

public class IkCorsPolicyProvider : ICorsPolicyProvider
{
    private CorsPolicy CreateCorsPolicy()
    {         
       CorsPolicy policy = new CorsPolicy     
       {        
          AllowAnyMethod = true,
          AllowAnyHeader = false,
          AllowAnyOrigin = false
       };

       // Some code to get the client allowed origins
       //.....
       //

       // set the allowed origins to the policy
       foreach (string allowedOrigin in allowedOrigins)
       {
          policy.Origins.Add(allowedOrigin);
       }

       policy.Headers.Add("content-type");
       policy.Headers.Add(UserContext.Key);
       policy.ExposedHeaders.Add("content-type");
       policy.ExposedHeaders.Add(UserContext.Key);

       return policy;           
    }

   public Task<CorsPolicy> GetCorsPolicyAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
       CorsPolicy policy = CreateCorsPolicy();
       return Task.FromResult(policy);
    }
}

Then in Register:

public static void Register(HttpConfiguration config)
{
    config.EnableCors(new IkCorsPolicyProvider());
     .....
    // rest of the implementation (Routes, etc...)
 }
Stunt
  • 21
  • 5

2 Answers2

0

You are actually get to the point. When you request to a server from a different origin, the navigator (Chrome) will make the request with an OPTIONS method (this will ask to the server what methods are expoxed).

For example, imagine your frontend is on 'http://104.131.62.190' and your backend on 'http://104.131.62.195'. Well, If you request an endpoint with POST method, Chrome will send an OPTIONS method (without headers) to the server asking if your backend allows POST method. If it allows, then server send a 200 and Chrome will send your POST request (with headers) and you will catch the response.

If your options method response with 401, then your CORS is not correctly enabled. Sometimes Chrome interrumpt the request for the time configuration. At this point there is nothing to do at frontend, your solution is at your backend server side.

Daniel Delgado
  • 4,813
  • 5
  • 40
  • 48
  • Thanks for the answer. Server side it is ok, because I have a successfully callback client side with the full body. There are just some missing headers (my specific added headers). – Stunt Feb 16 '18 at 07:37
0

In your server, make sure you add Access-Control-Expose-Headers : [HeaderName] for headers you want to access in angular.

e.g. to be able to access Authorization header in angular, your server must set this header as well

Access-Control-Expose-Headers: Authorization

And make sure to specify 'observe' :'response' in angular's http call options

https://angular.io/guide/http#reading-the-full-response

David
  • 33,444
  • 11
  • 80
  • 118
  • I will update my post because I have writtent a CorsPolicyProvider wich set the right headers. But it doesn't work... – Stunt Feb 16 '18 at 07:34