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).
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>
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 expected 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., for 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.
来源:https://stackoverflow.com/questions/32332882/missing-token-access-control-allow-headers-in-cors-header-access-control-allo