Chrome 不在 HTTPS 中发送 "if-none-match" header(但在 HTTP 中发送)

Chrome doesn't send "if-none-match" header in HTTPS (but sends it in HTTP)

tl;dr: Chrome 没有为 HTTPS 请求发送“If-None-Match”header,而是为 HTTP 请求发送它。 Firefox 始终在 HTTPS 和 HTTP 中发送“If-None-Match”。

当我遇到 Chrome 的奇怪行为时,我正在尝试优化我的节点服务器的 cookie 管理。我将尝试描述它并与 Firefox 进行比较。

首先,这是我用来测试的 HTTP 节点服务器:

#!/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) => {
    res.status(200).send(fs.readFileSync(pathUtils.join(__dirname, 'dummy.txt')));
});

server.listen(1234);

还有客户端代码:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
    </head>
    <body>
        <script>
            let test = fetch('http://localhost:1234/api/test', { mode: 'no-cors' })
                .then((res) => {
                    return res.text();
                })
                .then((resText) => console.log(resText));
        </script>
    </body>
</html>

我使用header“no-cache”强制客户端re-validate响应。 如果我已经正确理解了缓存的工作原理,我希望客户端发送带有“If-None-Match”的请求 header 具有先前请求的 e-tag 并且服务器响应 304代码。

这是我在 Firefox 中刷新页面时的结果(因此至少已收到一个响应)。我嵌入了请求的服务器日志 header。 这里 header “If-None-Match” 是客户端请求发送的,正如预期的那样。

现在与 Chrome 相同的测试给出:

好吧,这里 Chrome 显示了 200 响应代码,但在幕后,它实际上是服务器发送的 304 响应,此 wireshark 捕获显示了这一点:

如您所见,Chrome 发送带有正确 e-tag 的“If-None-Match”header,因此是 304 响应。

现在,让我们尝试使用 HTTPS。在服务器代码中,我只是将 require('http'); 替换为 require('https') 并在 createServer 选项中传递了我的 ssl 密钥(如 here 所述)

首先,Firefox 行为:

我已经包含了 wireshark 捕获。如您所见,一切正常,Firefox 具有预期的行为。

现在让我们看看与 Chrome 相同的事情:

这是我的问题:如您所见,“If-None-Match”不是由 Chrome 发送的。因此,正如预期的那样,服务器 returns 可以在 wireshark 捕获中看到一个 200 响应(我刷新了页面两次,这就是为什么有 2 次交换)。

有人知道为什么 Chrome 有这种奇怪的行为吗?

我认为这是因为您没有在设置中设置本地主机的证书。

转到设置并添加它:)

chrome settings capture