asp.netajaxasp.net-mvcasp.net-web-apimessage-handlers

Unable to get headers from jQuery AJAX request in ASP.NET Web API


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?


Solution

  • 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."