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