express/浏览器与缓存标头和 304 响应代码相关的行为

问题描述 投票:0回答:1

我正在尝试了解缓存标头和响应代码的行为。

最初我有一个如下所示的快速应用程序:

app.get("/users-a", async (req, res) => {

  await new Promise((res) => setTimeout(res, 3000));
  res.setHeader("Access-Control-Allow-Origin", "*");
  res.setHeader("Cache-Control", `public, max-age=10`);
  res.json(users);
});

本质上,我们模拟了需要 3000 毫秒的“数据库查找”,然后返回响应。响应缓存标头是

public, max-age=10

在浏览器中,我现在重复单击按钮来发出此请求,我们看到第一个请求需要 3000 毫秒,后续请求是立即的 - 它们使用浏览器的磁盘缓存,但 10 秒后发出 3000 毫秒的请求再次。

请注意,响应包含标头:

Etag: W/"1a-Q1ZzAew6rLbf4JEZbVarkQiSXKo"

这个Etag是由express自动应用的,请参阅这里的全面讨论:

etag 在expressjs 中如何工作

请求包含标头:

If-None-Match: W/"1a-Q1ZzAew6rLbf4JEZbVarkQiSXKo"

到目前为止,这对我来说都是有意义的。

我现在想模拟浏览器,现在有过时的数据,发出该请求并接收 304 状态代码 - 指示它使用其现有内容。

我们修改申请如下:

app.get("/users-b", async (req, res) => {
  res.setHeader("Access-Control-Allow-Origin", "*");

  const ifNoneMatch = req.headers["if-none-match"];

  if (ifNoneMatch && etags.has(ifNoneMatch)) {
    res.sendStatus(304);
  } else {
    await new Promise((res) => setTimeout(res, 3000));

    res.setHeader("Cache-Control", `public, max-age=${10}`);
    res.json(users);

    const etagValue = res.getHeader("etag");
    etags.add(etagValue);
  }
});

这很粗暴,但本质上我们将express生成的etag存储到一个集合中,然后如果收到带有if-none-match header的请求,则立即返回304,没有响应正文 - 客户端已经有了它.

我期望看到的是,在浏览器中我们会看到 304 响应。当然,快速代码确实沿着

res.sendStatus(304)
路径执行。

但我们看到的是,在网络选项卡中,浏览器有一个 200 响应,带有响应正文。响应不需要 3000 毫秒,表明缓存行为正常工作。

我想我的问题是 - 这就是浏览器对 304 状态代码的行为方式吗 - 它会将其转换为 200 响应而不向您显示?

express http browser-cache http-caching http-status-code-304
1个回答
0
投票

根据 Kevin Henry 的评论,这似乎是 Chromium 中的一个错误

我已经在 Chrome 129 中进行了测试,它似乎可以正常工作。

© www.soinside.com 2019 - 2024. All rights reserved.