21

I have two VS projects : one exposing MVC5 controllers, the other being an angular client. I want the angular client to be able to query the controllers. I read numerous threads and tried the following :

  • I added this in the server's web config:

    <system.webServer> <httpProtocol> <customHeaders> <clear /> <add name="Access-Control-Allow-Origin" value="*" /> </customHeaders> </httpProtocol> <system.webServer> 
  • I created and used the the following filter on the controller's action:

    public class AllowCrossSiteJsonAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "*"); base.OnActionExecuting(filterContext); } } 
  • In the angular client, I created the following interceptor :

    app.factory("CORSInterceptor", [ function() { return { request: function(config) { config.headers["Access-Control-Allow-Origin"] = "*"; config.headers["Access-Control-Allow-Methods"] = "GET, POST, OPTIONS"; config.headers["Access-Control-Allow-Headers"] = "Content-Type"; config.headers["Access-Control-Request-Headers"] = "X-Requested-With, accept, content-type"; return config; } }; } ]); app.config(["$httpProvider", function ($httpProvider) { $httpProvider.interceptors.push("CORSInterceptor"); }]); 

According to Firebug, this results in the following request :

OPTIONS //Login/Connect HTTP/1.1 Host: localhost:49815 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Origin: http://localhost:50739 Access-Control-Request-Method: POST Access-Control-Request-Headers: access-control-allow-headers,access-control-allow-origin,content-type Connection: keep-alive Pragma: no-cache Cache-Control: no-cache 

And the following response :

HTTP/1.1 200 OK Allow: OPTIONS, TRACE, GET, HEAD, POST Server: Microsoft-IIS/10.0 Public: OPTIONS, TRACE, GET, HEAD, POST X-SourceFiles: =?UTF-8?B?RDpcVEZTXElVV2ViXEdhcE5ldFNlcnZlclxBU1BTZXJ2aWNlc1xMb2dpblxDb25uZWN0?= Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET, POST, OPTIONS Access-Control-Allow-Headers: * Access-Control-Request-Headers: X-Requested-With, accept, content-type Date: Tue, 01 Sep 2015 13:05:23 GMT Content-Length: 0 

And still, Firefox blocks the request with the following message :

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:49815//Login/Connect. (Reason: missing token 'access-control-allow-headers' in CORS header 'Access-Control-Allow-Headers' from CORS preflight channel). 
1

4 Answers 4

30

Oftentimes, the threads that I read were suggesting several unecessary configuration steps, which created confusion. It's actually very simple...

For the simple purpose of sending a cross site request, from an angular client, to an ASP controller :

  • No angular interceptors are required.
  • No custom filters on the server side are required.
  • The only mandatory modification is to add this in the server's web.config

    <system.webServer> <httpProtocol> <customHeaders> <clear /> <add name="Access-Control-Allow-Origin" value="*" /> <add name="Access-Control-Allow-Headers" value="Content-Type"/> </customHeaders> </httpProtocol> </system.webServer> 
Sign up to request clarification or add additional context in comments.

2 Comments

For sailsjs see https://0.12.sailsjs.com/documentation/reference/configuration/sails-config-cors
This will not work in Firefox and is not best practice either. You should explicitly set (on the the server) the value of Access-Control-Allow-Origin to match the expected origin. If you need to test this on your local machine and encounter issues with localhost, just add the following line in your hosts file: 127.0.0.1 yourwebsite.local. After this step, configure the server to answer with Access-Control-Allow-Origin: yourwebsite.local. In case you don't have access to the backend, see this thread: stackoverflow.com/questions/3076414/…
17

The problem is, some browsers don’t yet allow the * wildcard for Access-Control-Allow-Headers. Specifically, Firefox 69 and earlier doesn’t. See https://bugzilla.mozilla.org/show_bug.cgi?id=1309358.

So to ensure you get correct behavior in all browsers, the Access-Control-Allow-Headers value you send back should explicitly list all the header names you actually need to access from your frontend code; e.g., in the case in the question: Access-Control-Allow-Headers: Content-Type.

A way you can make that happen without needing to hardcode all the header names is: Have your server-side code take the value of the Access-Control-Request-Headers request header the browser sends, and just echo that into the value of the Access-Control-Allow-Headers response header your server sends back.

Or else use some existing library to CORS-enable your server. Echoing the Access-Control-Request-Headers request-header value into the Access-Control-Allow-Headers response-header value is something most CORS libraries will typically do for you.

1 Comment

This answer is from 2015, and the argument of "Firefox 69 and earlier doesn’t allow the * wildcard" is still relevant... Since Firefox 68 is the latest stable release here in 2019 :-(
0

I tried in my .net c# mvc app and client app in angular 8 but it is not working. IN web.config, i added

<httpProtocol> <customHeaders> <clear /> <add name="Access-Control-Allow-Origin" value="http://localhost:4200" /> <add name="Access-Control-Allow-Headers" value="Content-Type"/> </customHeaders> </httpProtocol> 

In global.axax.cs file also, i added

 void MvcApplication_AuthenticateRequest(object sender, EventArgs e) { Context.Response.AddHeader("Access-Control-Allow-Origin", "http://localhost:4200"); } 

but it is not working. In chrome in response header it does show as :

Access-Control-Allow-Headers: Content-Type Access-Control-Allow-Origin: http://localhost:4200 Access-Control-Allow-Origin: http://localhost:4200

but in request header it shows as

Access-Control-Request-Headers: access-control-allow-origin,content-type,x-iphoneclientid

whereas it needs to have like

x-iphoneclientid : 8E72FF50-548B

since x-iphoneclientid is the token i validate in my filter class as

 protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) { if (request == null || request.RequestUri == null) { return null; } // Write your Authentication code here IEnumerable<string> monsterApiKeyHeaderValues = null; // Checking the Header values if (request.Headers.TryGetValues("x-iphoneclientid", out monsterApiKeyHeaderValues)) 

and above condition does not find so it rejects it and it does not reach to controller.

I even have put following in my controller

[EnableCors("", "", "*")]

can you guide please

Thanks

Comments

0

I had the same issue but other answers did not work for me, possibly due to working on a newer framework. Here is the official documentation from Microsoft for how to fix the issue as of 2023 https://learn.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-7.0 Below is a shorter explanation.

In the Program.cs file add the following code:

string myAllowSpecificOrigins = "myAllowSpecificOrigins"; builder.Services.AddCors( options => { options.AddPolicy( name: myAllowSpecificOrigins, policy => { policy.WithOrigins("https://localhost:44434") .AllowAnyHeader() .AllowAnyMethod(); } ); } ); app.UseCors(myAllowSpecificOrigins); 

This will allow the specified port(s) to make a cross-origin request. Be sure to replace the localhost address with the port you're using if it's different. It is also important to get the placement of this code correct in your Program.cs file. UseCors must be placed after UseRouting and before MapControllers (see link for more details and examples with context).

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.