title: CORS - request made after preflight request expects 'Access-Control-Allow-Credentials' to be true
body: <p>As always I will try to put my questions sweet and clean, as much as I can.</p>
  
  <p>I have to send CORS as a requirement request and I'm doing it through $.ajax and it looks like this:</p>
  
  <pre class="lang-js prettyprint-override"><code>$.ajaxSetup({
          beforeSend: function (jqXHR, options) {
              options.url = Utils.setUrlHostname(options.url);
              options.xhrFields = {
                  withCredentials: true
              };
              jqXHR.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
          }
      });
  </code></pre>
  
  <p>On the server side (php - zend framework) I'm handling headers like this:</p>
  
  <pre class="lang-php prettyprint-override"><code>public function OPTIONS_ProxyAction()
      {
          $this-&gt;getResponse()-&gt;setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET, POST, PUT, DELETE');
          $this-&gt;getResponse()-&gt;setHeader('Access-Control-Allow-Headers', 'Content-Type, x-requested-with');
          $this-&gt;getResponse()-&gt;setHeader('Access-Control-Allow-Credentials', 'true');
          $this-&gt;getResponse()-&gt;setBody(null);
          $this-&gt;_helper-&gt;viewRenderer-&gt;setNoRender(true);
      }
  </code></pre>
  
  <p>The preflight request headers looks fine and I'm getting 200 OK:</p>
  
  <p>Request Headers:</p>
  
  <pre><code>Host: domain1111.com
  User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:38.0) Gecko/20100101 Firefox/38.0
  Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  Accept-Language: en-US,en;q=0.5
  Accept-Encoding: gzip, deflate
  Origin: https://domain2222.com
  Access-Control-Request-Method: GET (this is seen as OPTIONS in network tab)
  Access-Control-Request-Headers: x-requested-with
  Connection: keep-alive
  Cache-Control: max-age=0
  </code></pre>
  
  <p>And Response Headers:</p>
  
  <pre><code>Access-Control-Allow-Credentials: true
  Access-Control-Allow-Headers: X-Requested-With, Content-Type
  Access-Control-Allow-Methods: OPTIONS, GET, POST, PUT, DELETE
  Access-Control-Allow-Origin: https://domain2222.com
  Cache-Control: max-age=0, s-maxage=0, no-store, no-cache, must-revalidate, post-check=0, pre-check=0
  Connection: Keep-Alive
  Content-Length: 0
  Content-Type: text/html
  Date: Thu, 11 Jun 2015 08:40:42 GMT
  Etag: "d41d8cd98f00b204e9800998ecf8427e"
  Expires: Thu, 01 Jan 1970 00:00:00 GMT
  Keep-Alive: timeout=5, max=100
  Pragma: no-cache
  Server: Apache
  Vary: X-CDN
  X-Frame-Options: SAMEORIGIN
  X-Ua-Compatible: IE=edge,chrome=1
  </code></pre>
  
  <p>I'm getting empty response which is fine, and a new request is sent to the same address, but the method is GET instead of OPTIONS and it looks like this:</p>
  
  <p>Request Headers: </p>
  
  <pre><code>Host: domain1111.com
  User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:38.0) Gecko/20100101 Firefox/38.0
  Accept: application/json, text/javascript, */*; q=0.01
  Accept-Language: en-US,en;q=0.5
  Accept-Encoding: gzip, deflate
  X-Requested-With: XMLHttpRequest
  Referer: https://domain2222.com/some/request
  Origin: https://domain1111.com
  Cookie: s1=533C36A9095C003A; 
  BGUID=some complicated guid here
  Connection: keep-alive
  Cache-Control: max-age=0
  </code></pre>
  
  <p>And Response:</p>
  
  <pre><code>Access-Control-Allow-Origin: https://domain2222.com
  Cache-Control: max-age=0, s-maxage=0, no-store, no-cache, must-revalidate, post-check=0, pre-check=0
  Connection: Keep-Alive
  Content-Length: 3278
  Content-Type: application/json
  Date: Thu, 11 Jun 2015 08:40:43 GMT
  Expires: Thu, 01 Jan 1970 00:00:00 GMT
  Keep-Alive: timeout=5, max=99
  Pragma: no-cache
  Server: Apache
  Vary: X-CDN
  X-Frame-Options: SAMEORIGIN
  </code></pre>
  
  <p>The problem is that after the real request is sent, I'm getting in Firefox:</p>
  
  <blockquote>
    <p>Cross-Origin Request Blocked: The Same Origin Policy disallows reading
    the remote resource at <a href="https://domain1111.com/some/request" rel="nofollow">https://domain1111.com/some/request</a>. (Reason:
    expected 'true' in CORS header 'Access-Control-Allow-Credentials')</p>
  </blockquote>
  
  <p>And similarly in Chrome: </p>
  
  <blockquote>
    <p>XMLHttpRequest cannot load <a href="https://domain1111.com/some/request" rel="nofollow">https://domain1111.com/some/request</a>.
    Credentials flag is 'true', but the 'Access-Control-Allow-Credentials'
    header is ''. It must be 'true' to allow credentials.</p>
  </blockquote>
  
  <p>Those errors occur when the second CORS request is finished.
  So after the first preflight request is sent, it returns with 200 OK and an empty response, which is fine; after the second request is sent I'm getting the errors listed above, with no data returned.</p>
  
  <p>Additionally, the Response tab in Firefox is giving me this message: </p>
  
  <pre><code>SyntaxError: JSON.parse: unexpected end of data at line 1 column 1 on the JSON data
  </code></pre>
  
  <p>I'm not sure whether during second request the property 'withCredential' is sent as well or not, and maybe the server is not returning:</p>
  
  <pre><code>'Access-Control-Allow-Credentials', 'true'
  </code></pre>
  
  <p>Why it's happening only with OPTIONS requests?</p>
  
  <p>Should I return those headers from the server, no matter what request method is? Or maybe there is something wrong with ajaxSetup? Maybe it shouldn't sent 'withCredentials: true' within the second CORS request? </p>
  
  <p><strong>Update:</strong></p>
  
  <blockquote>
    <p>The problem has been fixed by adding Access-Control-Allow-Credentials:
    true, to all responses returned by the server (PUT, GET, POST, DELETE, OPTIONS)</p>
  </blockquote>