title: Chrome doesn't send "if-none-match" header in HTTPS (but sends it in HTTP)
body: <p>tl;dr: Chrome is not sending &quot;If-None-Match&quot; header for HTTPS request but sends it for HTTP request. Firefox always send &quot;If-None-Match&quot;, both in HTTPS and HTTP.</p>
  <p>I was trying to optimize cookies management for my node server when I came across a weird behavior with Chrome. I will try to describe it and compare it with Firefox.</p>
  <p>First, here is the <strong>HTTP</strong> node server I'm using to test this:</p>
  <pre class="lang-js prettyprint-override"><code>#!/usr/bin/env node
  
  'use strict';
  
  const express = require('express');
  const cors = require('cors');
  const compression = require('compression');
  const pathUtils = require('path');
  const fs = require('fs');
  
  const http = require('http');
  let app = express();
  app.disable('x-powered-by');
  app.use(function (req, res, next) {
      res.set('Cache-control', 'no-cache');
      console.log(req.headers);
      next();
  });
  
  app.use(express.json({ limit: '50mb' }));
  app.use(cors());
  app.use(compression({}));
  
  let server = http.createServer(app);
  
  app.get('/api/test', (req, res) =&gt; {
      res.status(200).send(fs.readFileSync(pathUtils.join(__dirname, 'dummy.txt')));
  });
  
  server.listen(1234);
  
  </code></pre>
  <p>And there the client code :</p>
  <pre class="lang-html prettyprint-override"><code>&lt;!DOCTYPE html&gt;
  &lt;html lang=&quot;en&quot;&gt;
      &lt;head&gt;
          &lt;meta charset=&quot;UTF-8&quot; /&gt;
          &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot; /&gt;
          &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;
          &lt;title&gt;Document&lt;/title&gt;
      &lt;/head&gt;
      &lt;body&gt;
          &lt;script&gt;
              let test = fetch('http://localhost:1234/api/test', { mode: 'no-cors' })
                  .then((res) =&gt; {
                      return res.text();
                  })
                  .then((resText) =&gt; console.log(resText));
          &lt;/script&gt;
      &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  <p>I use the header &quot;no-cache&quot; to force the client to re-validate the response.
  If I've understood correctly how the cache work, I'm expecting client to send the  request with the &quot;If-None-Match&quot; header having the previous request's e-tag and the server responding with a 304 code.</p>
  <p>Here is the result when I refresh the page in Firefox (so at least one response has already be received). I embedded the server log of the request header.
  <a href="https://i.stack.imgur.com/3McdI.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/3McdI.png" alt="enter image description here" /></a>
  Here the header &quot;If-None-Match&quot; is sent by the client request, as expected.</p>
  <p>Now the same test with Chrome gives :</p>
  <p><a href="https://i.stack.imgur.com/ugmGR.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/ugmGR.png" alt="enter image description here" /></a></p>
  <p>Well, here Chrome shows a 200 response code, but under the hood, it's really a 304 response that is sent by the server, which is shown by this wireshark capture :</p>
  <p><a href="https://i.stack.imgur.com/ntkQb.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/ntkQb.png" alt="enter image description here" /></a></p>
  <p>As you can see, Chrome send the &quot;If-None-Match&quot; header with the correct e-tag, hence the 304 response.</p>
  <p>So now, let's try this with HTTPS. In the server code, I just replaced <code>require('http');</code> by <code>require('https')</code> and pass my ssl keys in <code>createServer</code> options (as described <a href="https://nodejs.org/en/knowledge/HTTP/servers/how-to-create-a-HTTPS-server/" rel="nofollow noreferrer">here</a>)</p>
  <p>So first, Firefox behaviour:</p>
  <p><a href="https://i.stack.imgur.com/JlGYp.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/JlGYp.png" alt="enter image description here" /></a></p>
  <p>I've included the wireshark capture. And as you can see, everything is right, Firefox has the expected behaviour.</p>
  <p>Now let's see the same thing with Chrome :</p>
  <p><a href="https://i.stack.imgur.com/micgY.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/micgY.png" alt="enter image description here" /></a></p>
  <p>Here is my problem : as you can see, &quot;If-None-Match&quot; is not sent by Chrome. So as expected, the server returns a 200 response which can be seen in the wireshark capture (I refreshed the page twice, that's why there are 2 exchanges).</p>
  <p>Do anyone have an idea on why Chrome has this weird behaviour?</p>