title: Safari not setting CORS cookies using JS Fetch API
body: <p>I am unable to get Safari to successfully apply <code>Set-Cookie</code> from server responses when using the Fetch API (actually, via the <a href="https://github.com/github/fetch" rel="noreferrer">fetch polyfill</a>). The same code works correctly in FF and Chrome (I tested using both native and polyfill <code>fetch</code>).</p>
  
  <ol>
  <li>The request is across domains;</li>
  <li>yes, I am setting <code>credentials: true</code>;</li>
  <li>the server does respond with a <code>Set-Cookie</code> header;</li>
  <li>subsequent requests are sent from Chrome and FF with cookie request headers, but Safari does not;</li>
  <li>the request uses HTTPS (the cert is self-signed and on a development domain but it seems to be accepted by Safari on regular requests); and</li>
  </ol>
  
  <p>Does someone know what the problem might be?</p>
  
  <p>I've read through the documentation and gone through many of the <a href="https://github.com/whatwg/fetch/issues" rel="noreferrer">closed bug reports</a>. Unless I missed something, I think maybe the problem is with the <a href="https://github.com/github/fetch#sending-cookies" rel="noreferrer">'default browser behaviour'</a> dealing with cookies and CORS -- and not with fetch (reading through the polyfill source code, it seems 100% ignorant of cookies). A few bug reports suggest a malformed server response can prevent cookies from being saved.</p>
  
  <p>My code looks like this:</p>
  
  <pre><code>function buildFetch(url, init={}) {
      let headers = Object.assign({}, init.headers || {}, {'Content-Type': 'application/json'});
      let params = Object.assign({}, init, { credentials: 'include', headers });
  
      return fetch(`${baseUrl}${url}`, params);
  }
  
  buildFetch('/remote/connect', {method: 'PUT', body: JSON.stringify({ code })})
  .then(response =&gt; response.json())
  .then(/* complete authentication */)
  </code></pre>
  
  <p>The actual authorization request is below. I am using cURL to get the exact request/response data, since Safari makes it hard to copy/paste it.</p>
  
  <pre><code>curl 'https://mydevserver:8443/api/v1/remote/connect' \
  -v \
  -XPUT \
  -H 'Content-Type: application/json' \
  -H 'Referer: http://localhost:3002/' \
  -H 'Origin: http://localhost:3002' \
  -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/602.4.8 (KHTML, like Gecko) Version/10.0.3 Safari/602.4.8' \
  --data-binary '{"token":"value"}'
  
  
  *   Trying 127.0.0.1...
  * Connected to mydevserver (127.0.0.1) port 8443 (#0)
  * TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
  * Server certificate: mydevserver
  &gt; PUT /api/v1/remote/connect HTTP/1.1
  &gt; Host: mydevserver:8443
  &gt; Accept: */*
  &gt; Content-Type: application/json
  &gt; Referer: http://localhost:3002/
  &gt; Origin: http://localhost:3002
  &gt; User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/602.4.8 (KHTML, like Gecko) Version/10.0.3 Safari/602.4.8
  &gt; Content-Length: 15
  &gt; 
  * upload completely sent off: 15 out of 15 bytes
  &lt; HTTP/1.1 200 OK
  &lt; Access-Control-Allow-Origin: http://localhost:3002
  &lt; Access-Control-Allow-Credentials: true
  &lt; Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Api-Key, Device-Key
  &lt; Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
  &lt; Access-Control-Expose-Headers: Date
  &lt; Content-Type: application/json; charset=utf-8
  &lt; Content-Length: 37
  &lt; Set-Cookie: express:sess=[SESSIONKEY]=; path=/; expires=Fri, 17 Feb 2017 15:30:01 GMT; secure; httponly
  &lt; Set-Cookie: express:sess.sig=[SIGNATURE]; path=/; expires=Fri, 17 Feb 2017 15:30:01 GMT; secure; httponly
  &lt; Date: Fri, 17 Feb 2017 14:30:01 GMT
  &lt; Connection: keep-alive
  &lt; 
  * Connection #0 to host mydevserver left intact
  {"some":"normal","response":"payload"}
  </code></pre>