Search code examples
corsasp.net-web-api2angular-resource

Web API CORS Angular $resource


I have a Web API constructed in VS2012 using MVC4 and Web API 2. The front end is developed in AngularJS using ui-grid. The VS2012 JavaScript editor is not really very friendly, so I am using JetBrains WebForm 9 to develop the front end. This means that every request to the backen is a CORS request.

In the front end I got it all working using $http but since this project, though useful, is being used by me to learn I decided to convert to use $resource instead. But the $http successfully used the GET, POST, OUT and DELETE interfaces in the backend so I know they all work.

However, when I convert the code to use $resource, the query works fine but the save does not. It yields the following error in the JaveScript console.

XMLHttpRequest cannot load http://localhost:51274/api/series. Request header field Content-Type is not allowed by Access-Control-Allow-Headers.

It never gets as far as the POST, instead it fails after an OPTIONS call. Fiddler is running so I post the HttpRequest and the HttpResponse below. Remember, in the $http implementation the POST worked fine.

OPTIONS http://localhost:51274/api/series HTTP/1.1
Host: localhost:51274
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Access-Control-Request-Method: POST
Origin: http://localhost:63342
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.99 Safari/537.36
Access-Control-Request-Headers: accept, content-type
Accept: */*
Referer: http://localhost:63342/AWSOrderEntry/index.html
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8

and the response is

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?YzpcdXNlcnNcbWhvcnRvbi5ucmhcZG9jdW1lbnRzXHZpc3VhbCBzdHVkaW8gMjAxMlxQcm9qZWN0c1xBV1NPcmRlckVudHJ5XEFXU09yZGVyRW50cnlcYXBpXHNlcmllcw==?=
X-Powered-By: ASP.NET
Access-Control-Allow-Origin: *
Access-Control_Allow-Headers: Content-Type
Access_Control-Allow-Methods: *
Date: Mon, 16 Feb 2015 04:32:52 GMT
Content-Length: 0

I am assuming from this that $resource, before doing a CORS does a "pre-flight check" by sending the OPTIONS which effectively says can I POST against this URL? The answer appears to be YES and use can use the header Content-Type. B ut then $resource sees this and complains that it is not allowed to send Content-Type in the request. So it issues a message and errors the call without ever issuing the POST. The Fiddler never shows the POST and the backendenter code here when in DEBUG mode doesn't halt on the POST request in the Controller.

The following is then entry in Web.config.

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

It seems to me that either there is a bug in $resource or, and this is much more likely, I have done something really silly and don't fully understand it.


Solution

  • You have an underscore rather than a dash in your Access-Control-Allowed-Headers header: Access-Control_Allow-Headers: Content-Type

    should be:

    Access-Control-Allow-Headers: Content-Type