I have a C# SOAP web service along with some custom IHTTPHandler
classes deployed to https://localhost:123
. I have an HTML page on http://localhost
trying to use jQuery to send an AJAX POST request to one of those handlers. I get the following every time:
XMLHttpRequest cannot load
https://localhost:123/(S(the_session_id))/MyHandler.ashx
. Originhttp://localhost
is not allowed by Access-Control-Allow-Origin.
I have tried creating a CrossOriginModule
module and CrossOriginHandler
handler like in this question, updating my web.config as they suggest. I have tried adding context.Response.AppendHeader("Access-Control-Allow-Headers", "x-requested-with");
to my handler's ProcessRequest
, as suggested in this question. I tried following the steps in this blog post about adding OPTIONS
to SimpleHandlerFactory-Integrated-4.0
in system.webServer
/handlers
in the web.config. Nothing helps.
Here is my handler's ProcessRequest
:
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "application/json";
context.Response.AppendHeader("Access-Control-Allow-Origin", "*");
context.Response.AppendHeader("Access-Control-Allow-Headers", "x-requested-with");
context.Response.Write( /* some JSON string */ );
}
Here's a relevant section of my web.config:
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
<modules runAllManagedModulesForAllRequests="true">
<add name="CrossOriginModule" preCondition="managedHandler" type="MyNamespace.CrossOriginModule, MyNamespace, Version=1.0.0.0, Culture=neutral" />
</modules>
<handlers>
<add name="CrossOrigin" verb="OPTIONS" path="*" type="MyNamespace.CrossOriginHandler, MyNamespace, Version=1.0.0.0, Culture=neutral" />
<remove name="SimpleHandlerFactory-Integrated-4.0" />
<add name="SimpleHandlerFactory-Integrated-4.0" path="*.ashx" verb="GET,HEAD,POST,DEBUG,OPTIONS" type="System.Web.UI.SimpleHandlerFactory" resourceType="Unspecified" requireAccess="Script" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="MyHandler" verb="*" path="MyHandler.ashx" type="MyNamespace.MyHandler, MyNamespace, Version=1.0.0.0, Culture=neutral" />
</handlers>
</system.webServer>
Using jQuery 1.7.2, here is how I'm making the request to my handler:
$.ajax({
url: url,
data: {user: userName, pass: password},
type: 'POST',
dataType: 'json',
success: function(data, textStatus, jqXHR) {
...
}
});
I also am not using cookies for sessions on the server, so <sessionState cookieless="true" />
is in my web.config, if this matters. My server is IIS 7.5.
I'm able to use JSONP for most requests because I'm not passing sensitive data in the URL. However, for this one handler, I need to do a regular POST because it involves sending a plain-text password. It's over SSL, but this post recommends not passing sensitive data in the URL even over SSL. So I need to do a POST request via AJAX to an https URL and get back JSON, and the requesting page won't be on the same host as the server.
Edit: some other things I've tried:
Changing my web.config httpProtocol
section:
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Methods" value="OPTIONS,POST,GET"/>
<add name="Access-Control-Allow-Headers" value="x-requested-with"/>
<add name="Access-Control-Allow-Origin" value="*" /><!-- Also tried http://localhost -->
</customHeaders>
</httpProtocol>
I added context.Response.AppendHeader("Access-Control-Allow-Methods", "POST");
to ProcessRequest
. I also tried context.Response.AppendHeader("Access-Control-Allow-Methods", "POST,OPTIONS");
and changing my jQuery ajax
options to include contentType: 'application/json'
, which causes it to make an OPTIONS request instead of POST--this still fails.
Am I supposed to list all my custom IHTTPHandler
classes in web.config in <handlers>
? I have MyHandler
there now, with its verb="*"
, but it doesn't seem to help.
Edit: so some further strangeness. It looks like my request is actually going through on the server side when I POST to it, based on my logging output, but the browser acts like it got rejected, still telling me the 'origin localhost not allowed'. So my AJAX POST to the server authenticates me like I want it to do, but the browser cancels the request and an error shows up in the Chrome console, so my success
event handler doesn't trigger.