Very confused by cors with fetch and when an options request is made
<p>I have the following code that uses <a href="https://github.com/github/fetch" rel="nofollow noreferrer">whatwg fetch</a>:</p>

<pre><code>  const headers = new Headers();

  //uncommenting this causes the preflight options request to be sent 
  //headers.append('x-something', 'foo');

  const response = await fetch('http://localhost:5000/api/managers', {
    headers,
    credentials: 'include'
  });
</code></pre>

<p>The above code does not make a preflight options request unless I uncomment this line:</p>

<pre><code> //headers.append('x-something', 'foo');
</code></pre>

<p>I have the server configured like this to allow the localhost request:</p>

<pre><code>app.use(cors({
  origin: 'http://localhost:4040'
}));
</code></pre>

<p>If I make the request with the <code>credentials: 'include'</code> option, I get the following error in the chrome browser:</p>

<blockquote>
  <p>Fetch API cannot load <a href="http://localhost:5000/api/managers" rel="nofollow noreferrer">http://localhost:5000/api/managers</a>. Credentials
  flag is 'true', but the 'Access-Control-Allow-Credentials' header is
  ''. It must be 'true' to allow credentials. Origin
  '<a href="http://localhost:4040" rel="nofollow noreferrer">http://localhost:4040</a>' is therefore not allowed access.</p>
</blockquote>

<p>If I remove <code>credentials: 'include'</code> but have the custom header like this:</p>

<pre><code>  headers.append('x-something', 'foo');

  const response = await fetch('http://localhost:5000/api/managers', {
    headers
  });
</code></pre>

<p>Then the chrome network tab just shows an OPTIONS request with a <code>204 No Content</code> response even though a JSON response is returned from the server.</p>

<p>I don't understand why the chrome network tab is not showing a GET request with the JSON response as it is happening.</p>

<p>The request and response looks like this with a 204 no content response:</p>

<pre><code>Request URL:http://localhost:5000/api/managers
Request Method:OPTIONS
Status Code:204 No Content
Remote Address:[::1]:5000
Response Headers
view source
Access-Control-Allow-Headers:x-something
Access-Control-Allow-Methods:GET,HEAD,PUT,POST,DELETE,PATCH
Access-Control-Allow-Origin:http://localhost:4040
Connection:keep-alive
Date:Wed, 02 Nov 2016 21:23:24 GMT
Vary:Accept-Encoding
Request Headers
view source
Accept:*/*
Accept-Encoding:gzip, deflate, sdch, br
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:x-something
Access-Control-Request-Method:GET
Cache-Control:no-cache
Connection:keep-alive
Host:localhost:5000
Origin:http://localhost:4040
Pragma:no-cache
Referer:http://localhost:4040/base/winratio
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36
Name
managers
/api
info?t=1478121804370
/sockjs-node
</code></pre>

<p>IF I make the code simply this:</p>

<pre><code>  const response = await fetch('http://localhost:5000/api/managers', {
  });
</code></pre>

<p>Then the google chrome network tab just shows a GET request with a 200 HTTP response and the json it is returning:</p>

<pre><code>Request URL:http://localhost:5000/api/managers
Request Method:GET
Status Code:200 OK
Remote Address:[::1]:5000
Response Headers
view source
Access-Control-Allow-Origin:http://localhost:4040
Connection:keep-alive
Content-Length:1104
Content-Type:application/json; charset=utf-8
Date:Wed, 02 Nov 2016 21:35:21 GMT
Vary:Accept-Encoding
X-Content-Type-Options:nosniff
X-DNS-Prefetch-Control:off
X-Download-Options:noopen
X-Frame-Options:SAMEORIGIN
X-XSS-Protection:1; mode=block
Request Headers
view source
Accept:*/*
Accept-Encoding:gzip, deflate, sdch, br
Accept-Language:en-US,en;q=0.8
Cache-Control:no-cache
Connection:keep-alive
Host:localhost:5000
Origin:http://localhost:4040
Pragma:no-cache
Referer:http://localhost:4040/base/winratio
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36
Name
</code></pre>