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
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。
现在与 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