I have an ascx page GetToken.ashx.
public void ProcessRequest (HttpContext context) {
context.Response.ContentType = "text/plain";
context.Response.AppendHeader("Access-Control-Allow-Origin", "*");
context.Response.Write(Token.CreateToken());
}
When I AJAX to this page, it returns the following headers:
Request Method:GET
Status Code:200 OK
Access-Control-Allow-Origin:*
Cache-Control:private
Content-Length:36
Content-Type:text/plain; charset=utf-8
Date:Tue, 14 Apr 2015 17:20:53 GMT
Server:Microsoft-IIS/8.5
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET
When the page that makes the AJAX request is placed in a sandboxed iFrame, it shows the error:
XMLHttpRequest cannot load https://127.0.0.1:112/handlers/gettoken.ashx. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
And returns the headers:
Request Method:OPTIONS
Status Code:200 OK
Allow:OPTIONS, TRACE, GET, HEAD, POST
Content-Length:0
Date:Tue, 14 Apr 2015 17:30:14 GMT
Public:OPTIONS, TRACE, GET, HEAD, POST
Server:Microsoft-IIS/8.5
X-Powered-By:ASP.NET
I cannot seem to get the OPTIONS request to add the header. Adding allow-same-origin to the sandbox properties changes the request to a GET, but I do not wish to grant the iFrame those permissions.
ajaxSetup({ headers: { 'custom-header': 'some value' } }); // Sends your custom header $. ajax({ url: 'edureka/co' }); // Overwrites the default header with a new header $. ajax({ url: 'edureka/co', headers: { 'some-other-header': 'some value' } }); To add a header to every request then use the beforeSend hook with $.
The headers are additional key-value pairs send along with ajax request using the XMLHttpRequest object. An asynchronous HTTP request to the server by using The ajax() function and by including the header it describes to the server what kind of response it accept.
processData. If set to false it stops jQuery processing any of the data. In other words if processData is false jQuery simply sends whatever you specify as data in an Ajax request without any attempt to modify it by encoding as a query string.
getResponseHeader() The XMLHttpRequest method getResponseHeader() returns the string containing the text of a particular header's value.
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.1
Host: 127.0.0.1:49253
Connection: keep-alive
Cache-Control: max-age=0
Access-Control-Request-Method: GET
Origin: null
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36
Access-Control-Request-Headers: accept, x-requested-with
Accept: */*
Referer: http://127.0.0.1:49253/SandboxTest.aspx?sandboxed=true
Accept-Encoding: gzip, deflate, sdch
Accept-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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With