3

I have an ASP.NET WebAPI client which has the following configuration which allows any cross-domain POST and GET calls:

public static void Register(HttpConfiguration config)
{
    config.EnableCors(new EnableCorsAttribute("*", "*", "GET,POST"));

    // other unrelated configurations
}

I have AJAX calls to my WebAPI application and all of them are failing with a CORS prevention message in a console.

The following AJAX request fails:

$.ajax({
    url: "myserver:8081/User/Get",
    data: {
        "Id": 12
    },
    type: "POST",
    dataType: "json",
    contentType: "application/json; encoding=utf-8"
});

Why does this happen and how to solve this?

Anders
  • 8,307
  • 9
  • 56
  • 88
Yeldar Kurmangaliyev
  • 33,467
  • 12
  • 59
  • 101

1 Answers1

6

I have spent a bunch of time "fighting" with WebAPI CORS when suddenly I have understood that the problem is in AJAX call. This request executes successfully:

$.ajax({
    url: "myserver:8081/User/Get",
    data: {
        "Id": 12
    },
    type: "POST",
    dataType: "json",
    // contentType: "application/json; encoding=utf-8"
});

According to jQuery.ajax() documentation,

For cross-domain requests, setting the content type to anything other than application/x-www-form-urlencoded, multipart/form-data, or text/plain will trigger the browser to send a preflight OPTIONS request to the server.

Browser is preflighting the request to look for CORS headers and discover if server allows cross-domain requests and making a real request is safe. If the request is acceptable, it will then send the real request.

A browser sends a preflight request is:

  • HTTP method is not GET, POST or HEAD;
  • or if Content-Type is not application/x-www-form-urlencoded, multipart/form-data or text/plain;
  • or if any custom HTTP headers are set.

So, Chrome sends OPTIONS "preflight" request. Insofar as I allow only POST and GET requests at the server, the browser thinks that it is a CORS violation and denies request.

This StackOverflow question is directly related to this question and explains what is "preflight" request and why does a browser need to send it.

The solution was as simple as the problem cause - don't specify Content-Type in cross-domain AJAX calls.

If you need to specify custom headers or Content-Type for your requests, you can implement a specal handler which will allow preflight requests. This StackOverflow article describes how to do this.

I hope that it will help someone to save time.

Community
  • 1
  • 1
Yeldar Kurmangaliyev
  • 33,467
  • 12
  • 59
  • 101