title: cannot POST to IHTTPHandler class, origin not allowed by Access-Control-Allow-Origin
body: <p>I have a C# SOAP web service along with some custom <code>IHTTPHandler</code> classes deployed to <code>https://localhost:123</code>.  I have an HTML page on <code>http://localhost</code> trying to use jQuery to send an AJAX POST request to one of those handlers.  I get the following every time:</p>
  
  <blockquote>
    <p>XMLHttpRequest cannot load <code>https://localhost:123/(S(the_session_id))/MyHandler.ashx</code>. Origin <code>http://localhost</code> is not allowed by Access-Control-Allow-Origin.</p>
  </blockquote>
  
  <p>I have tried creating a <code>CrossOriginModule</code> module and <code>CrossOriginHandler</code> handler like in <a href="https://stackoverflow.com/questions/6588447/support-options-request-header-in-aspx-page">this question</a>, updating my web.config as they suggest.  I have tried adding <code>context.Response.AppendHeader("Access-Control-Allow-Headers", "x-requested-with");</code> to my handler's <code>ProcessRequest</code>, as suggested in <a href="https://stackoverflow.com/questions/5750696/how-to-get-a-cross-origin-resource-sharing-cors-post-request-working">this question</a>.  I tried following the steps in <a href="http://www.chrisweldon.net/blog/2012/04/13/jquery-file-uploader/" rel="nofollow noreferrer">this blog post</a> about adding <code>OPTIONS</code> to <code>SimpleHandlerFactory-Integrated-4.0</code> in <code>system.webServer</code>/<code>handlers</code> in the web.config.  Nothing helps.</p>
  
  <p>Here is my handler's <code>ProcessRequest</code>:</p>
  
  <pre><code>    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 */ );
      }
  </code></pre>
  
  <p>Here's a relevant section of my web.config:</p>
  
  <pre><code>&lt;system.webServer&gt;
    &lt;httpProtocol&gt;
      &lt;customHeaders&gt;
        &lt;add name="Access-Control-Allow-Origin" value="*" /&gt;
      &lt;/customHeaders&gt;
    &lt;/httpProtocol&gt;
    &lt;modules runAllManagedModulesForAllRequests="true"&gt;
      &lt;add name="CrossOriginModule" preCondition="managedHandler" type="MyNamespace.CrossOriginModule, MyNamespace, Version=1.0.0.0, Culture=neutral" /&gt;
    &lt;/modules&gt;
    &lt;handlers&gt;
      &lt;add name="CrossOrigin" verb="OPTIONS" path="*" type="MyNamespace.CrossOriginHandler, MyNamespace, Version=1.0.0.0, Culture=neutral" /&gt;
      &lt;remove name="SimpleHandlerFactory-Integrated-4.0" /&gt;
      &lt;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" /&gt;
      &lt;add name="MyHandler" verb="*" path="MyHandler.ashx" type="MyNamespace.MyHandler, MyNamespace, Version=1.0.0.0, Culture=neutral" /&gt;
    &lt;/handlers&gt;
  &lt;/system.webServer&gt;
  </code></pre>
  
  <p>Using jQuery 1.7.2, here is how I'm making the request to my handler:</p>
  
  <pre><code>$.ajax({
      url: url,
      data: {user: userName, pass: password},
      type: 'POST',
      dataType: 'json',
      success: function(data, textStatus, jqXHR) {
          ...
      }
  });
  </code></pre>
  
  <p>I also am not using cookies for sessions on the server, so <code>&lt;sessionState cookieless="true" /&gt;</code> is in my web.config, if this matters.  My server is IIS 7.5.</p>
  
  <p>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 <a href="https://stackoverflow.com/questions/2629222/is-querystring-parameters-secure-in-https-http-ssl">this post</a> 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.</p>
  
  <p><strong>Edit:</strong> some other things I've tried:</p>
  
  <p>Changing my web.config <code>httpProtocol</code> section:</p>
  
  <pre><code>&lt;httpProtocol&gt;
    &lt;customHeaders&gt;
      &lt;add name="Access-Control-Allow-Methods" value="OPTIONS,POST,GET"/&gt;
      &lt;add name="Access-Control-Allow-Headers" value="x-requested-with"/&gt;
      &lt;add name="Access-Control-Allow-Origin" value="*" /&gt;&lt;!-- Also tried http://localhost --&gt;
    &lt;/customHeaders&gt;
  &lt;/httpProtocol&gt;
  </code></pre>
  
  <p>I added <code>context.Response.AppendHeader("Access-Control-Allow-Methods", "POST");</code> to <code>ProcessRequest</code>.  I also tried <code>context.Response.AppendHeader("Access-Control-Allow-Methods", "POST,OPTIONS");</code> and changing my jQuery <code>ajax</code> options to include <code>contentType: 'application/json'</code>, which causes it to make an OPTIONS request instead of POST--this still fails.</p>
  
  <p>Am I supposed to list all my custom <code>IHTTPHandler</code> classes in web.config in <code>&lt;handlers&gt;</code>?  I have <code>MyHandler</code> there now, with its <code>verb="*"</code>, but it doesn't seem to help.</p>
  
  <p><strong>Edit:</strong> 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 <code>success</code> event handler doesn't trigger.</p>