Header not being set for OPTIONS Ajax request Header not being set for OPTIONS Ajax request ajax ajax

Header not being set for OPTIONS Ajax request


I assume that you meant to write ashx, not ascx. The presence of the ProcessRequest (HttpContext context) method suggests it's a generic handler and not a user control.

I've made a very simple page to test with:

<%@ Page Language="C#" AutoEventWireup="true" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head runat="server">    <title></title>    <script type="text/javascript" src="Scripts/jquery-1.4.1.js"></script></head><body>    <div id="testCorsDiv">    </div>    <script type="text/javascript">        $.ajax({            type: "GET",            url: "/Handler/testCors.ashx",            dataType: "text",            success: function (theData) { $("#testCorsDiv").text(theData); },            error: function (theData) { alert('error'); }        });    </script>    <% if(string.IsNullOrEmpty(Request.QueryString["sandboxed"])) { %>    <iframe src="http://127.0.0.1:49253/SandboxTest.aspx?sandboxed=true" sandbox="allow-scripts" width="600">    </iframe>    <% } %></body></html>

I load the page on http://localhost:49253/SandboxTest.aspx. The page then makes an ajax request to http://localhost:49253/Handler/testCors.ashx and puts the output from that into the testCorsDiv div. This generates a straight GET to the handler (since it's coming from the same origin) and the output gets inserted.

In the page is also a sandboxed iframe which loads the same page using the url http://127.0.0.1:49253/SandboxTest.aspx. The ?sandboxed=true is there to prevent the iframe from recursively loading an inner iframe. The page loaded in the iframe will then try to make an ajax request to http://127.0.0.1:49253/Handler/testCors.ashx and display the output in it's own copy of the testCorsDiv div.

As long as the sandboxed iframe has allow-scripts this works like a charm. The iframe generates an OPTIONS request looking like this (from Fiddler, tested with Chrome):

OPTIONS http://127.0.0.1:49253/Handler/testCors.ashx HTTP/1.1Host: 127.0.0.1:49253Connection: keep-aliveCache-Control: max-age=0Access-Control-Request-Method: GETOrigin: nullUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90     Safari/537.36Access-Control-Request-Headers: accept, x-requested-withAccept: */*Referer: http://127.0.0.1:49253/SandboxTest.aspx?sandboxed=trueAccept-Encoding: gzip, deflate, sdchAccept-Language: fi-FI,fi;q=0.8,en-US;q=0.6,en;q=0.4

My testCors.ashx handler then spits out some headers that says that this looks ay-ok and the browser then follows up with a GET and it just works.

The testCors.ashx does this:

public void ProcessRequest(HttpContext context){    context.Response.ContentType = "text/plain";    context.Response.AppendHeader("Access-Control-Allow-Origin", "*");    context.Response.AppendHeader("Access-Control-Allow-Headers", "content-type, x-requested-with, accept");    context.Response.AppendHeader("Access-Control-Allow-Methods", "POST, OPTIONS, GET");    context.Response.Write("Hello World");}

So my testing suggests that it should be possible to do what you want. One thing though that might be an issue is if your handler is only accessible to authenticated/authorized users. As you can see the OPTIONS request has not sent a cookie to the handler. But on the other hand your question says that the response to you options request is Status Code:200. I suppose that would be some 4** if a required authentication cookie was missing.

Wrapping up, I don't really know what's wrong in your case, but maybe (?) my simple sample page can give you some clues that will help you find the issue yourself.


Make sure you have IIS setting to allow OPTION to that handler - deployed to app having say App pool name "web-app" and corresponding handler mapping should allow OPTION request.

Following are the steps to do that.

  • select required app pool
  • Click on handler mappings
  • select *.ashx and double click on the corresponding handler , click on Request Restriction , see if you have option verb there, if not, add that.

Above mentioned here - http://www.chrisweldon.net/blog/2012/04/13/jquery-file-uploader/

You may need to use following code.

public void ProcessRequest (HttpContext context) {    context.Response.ContentType = "text/plain";    context.Response.AddHeader("Access-Control-Allow-Origin", "*");    // You can try adding requested origin here instead of * like this - Request.Headers["Origin"] or only the specific domain, in your case it is -https://127.0.0.1:112    if (HttpContext.Current.Request.HttpMethod == "OPTIONS")    {        context.Response.AddHeader("Access-Control-Allow-Methods", "POST, PUT, DELETE");        context.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");        context.Response.AddHeader("Access-Control-Max-Age", "1728000");    }    context.Response.Write(Token.CreateToken());}

I have explained this in my blog. This was for WCF, but it should work for your case too! You might need to change * for allowed origin to requested origin, as * has security issue, it allows all domains to make CORS call.


Can you try adding the below code in both of your HTML and iFrame page (in the HTML DOC) and check if it works?

<script>document.domain = 'myDomain.com'</script>

Note: Please replace the 'myDomain' with appropriate domain name of the domain you are using (the origin)