0

I have an ASP.NET Web API which is hosted on Azure. I have integrated HTTP Message handler to that API. The message handler is getting hit when I am hitting it using AJAX call. I am also sending some request header in my AJAX call. The problem is I am not getting header sent from AJAX call to Message Handler integrated in Web API. Refer image: Debugger screenshot

Below is the code of my AJAX request:

$.ajax({
    url: "https://someservicename.azurewebsites.net/Service/RequestHandler",
    beforeSend: function (xhr) {
        xhr.setRequestHeader('Token', '86810e135958961ad4880ad');
    },
    type: "POST",
    crossDomain: true,
    data: {
        param: "Passed Parameter"
    },
    success: function (msg) {
        console.log(msg);
    },
    error: function (XMLHttpRequest, textStatus, errorThrown) {
        console.log(textStatus);
    }
});

The message handler in Web API looks like below:

protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
    string authToken;
    try
    {
        authToken = request.Headers.GetValues("Token").FirstOrDefault();

        if (authToken != "86810e135958961ad4880ad")
        {

            return await Task.Factory.StartNew(() =>
            {
                return new HttpResponseMessage(HttpStatusCode.BadRequest)
                {
                    Content = new StringContent("Unauthorized access!")
                };
            });
        }
        else
        {
            return await base.SendAsync(request, cancellationToken);
        }
    }
    catch (System.InvalidOperationException)
    {
        return null;
    }
}

When I run the the code from my IIS localhost the request which is sent is something like below:

Accept:*/*
Accept-Encoding:gzip, deflate, sdch, br
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:token
Access-Control-Request-Method:POST
Connection:keep-alive
Host:someservicename.azurewebsites.net
Origin:http://localhost:12522
Referer:http://localhost:12522/pocppd.html
User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36

And the response which I getting in console is:

https://someservicename.azurewebsites.net/Service/RequestHandler. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:12522' is therefore not allowed access. The response had HTTP status code 500.

With POSTMAN client the request works fine but from localhost it returns an error. Please let me know the reason for not getting header in my message handler?

Saurabh Verma
  • 35
  • 1
  • 6
  • Response on console -which will brings dozens of [results](https://www.google.com.tr/search?q=Response+to+preflight+request+doesn%27t+pass+access+control+check%3A+No+%27Access-Control-Allow-Origin%27&oq=Response+to+preflight+request+doesn%27t+pass+access+control+check%3A+No+%27Access-Control-Allow-Origin%27&aqs=chrome..69i57j69i59.119j0j7&sourceid=chrome&ie=UTF-8) when being searched- simply tells you that the origin of which request comes from is not allowed on the server as because of CORS standard. Marius' answer is a way to make server repsonse to requests from your `localhost`. – ibubi Apr 13 '17 at 11:33

2 Answers2

1

You have to add this in your Web.config (you can change values as you need):

    <httpProtocol>
        <customHeaders>
            <add name="Access-Control-Allow-Origin" value="*" />
            <add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept, Authorization, Token" />
            <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE" />
        </customHeaders>
    </httpProtocol>

Before your request, an OPTIONS request is sent to ensure that you are allowed to perform the request. As the error says, "Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.". Adding above lines in Web.config will pass the needed header.

MDN says: "Unlike simple requests (discussed above), "preflighted" requests first send an HTTP OPTIONS request header to the resource on the other domain, in order to determine whether the actual request is safe to send. Cross-site requests are preflighted like this since they may have implications to user data."

Marius Orha
  • 670
  • 1
  • 9
  • 26
  • I added above in my web.config but still facing the same issue...it breaks in preflight request...header from AJAX getting sent as `Access-Control-Request-Headers:authorization` _without_ its value – Saurabh Verma Apr 13 '17 at 11:51
  • Thanks @Marius, what I figured out is as my request is preflighted it is not carrying the custom headers, when actual request after preflight is sent the custom header goes along with it! – Saurabh Verma Apr 13 '17 at 17:48
1

Try this

$.ajax({
    url: "https://someservicename.azurewebsites.net/Service/RequestHandler",
    headers: {
            "Token": "86810e135958961ad4880ad"
        },    
    type: "POST",
    crossDomain: true,
    data: {
        param: "Passed Parameter"
    },
    success: function (msg) {
        console.log(msg);
    },
    error: function (XMLHttpRequest, textStatus, errorThrown) {
        console.log(textStatus);
    }
});