调用 app.get() 一直返回 304 Not Modified

阅读时长 5 分钟读完

在前端开发中,我们经常会使用到后端接口来获取数据或者进行其他操作。而在使用 Express 框架时,经常会遇到调用 app.get() 返回 304 Not Modified 的问题。这个问题看起来非常简单,但是背后涉及到的知识点却非常多。本文将详细介绍这个问题及其解决方法。

问题描述

假设我们有一个网站,需要从后端获取一些数据。我们使用 Express 框架来搭建后端,并在后端定义了如下的路由:

在前端代码中,我们使用 axios 请求这个接口,代码如下:

我们希望每次请求都能获取到最新的数据,但是实际上在多次请求后发现,每次获取到的数据都是相同的。通过查看 Chrome 开发者工具,发现控制台返回的状态码一直是 304 Not Modified。

问题原因

在 HTTP 协议中,如果客户端通过浏览器访问一个网站,并在浏览器中保存了这个网站的缓存,那么在下次访问时,浏览器会自动从缓存中获取数据,而不是直接从服务器请求。这个过程就称为 HTTP 缓存。

当客户端发送一个带有 If-None-Match 和 If-Modified-Since 头信息的请求到服务器,服务器会自动比较客户端提供的 ETag 以及 If-Modified-Since 和服务器上的版本号及修改时间,如果相同则服务器会返回 304 Not Modified,客户端会从缓存中获取数据,这样就能节省带宽和服务器资源,提高访问速度。

在 Express 中,如果我们没有正确配置缓存,就会导致每次请求都返回 304 Not Modified,从而出现上述问题。

解决方法

1. 指定 Cache-Control

我们可以通过设置 Response Headers 中的 Cache-Control 头信息来指定缓存的类型以及过期时间。Cache-Control 可以设置以下几个值:

  • public:可以被任何一个方向缓存,包括浏览器以及中间代理服务器;
  • private:只能被浏览器缓存,不能被中间代理服务器缓存;
  • no-cache:不能被任何方向缓存,需要重新从服务器获取;
  • max-age:指定缓存的有效期,单位为秒。

我们可以通过如下代码来设置 Cache-Control:

2. 指定 ETag

在我们的 Response Headers 中可以指定 ETag 和 Last-Modified 头信息。ETag 是一个字符串,表示当前版本的资源。当客户端请求时,服务器会返回当前资源的 ETag,客户端会在请求头信息中发送 If-None-Match 字段,服务器会比较两个值是否一致,如果一致,则返回 304 Not Modified。如果我们没有设置 ETag 或者 ETag 不正确,就会导致每次请求都返回 200 OK。

我们可以通过如下代码来设置 ETag:

-- -------------------- ---- -------
-------------------- ----- ---- -- -
  ----- ---- - -
    ----- -------
    ---- --
  --
  ----- ---- - -------------------------------------------------------------------------------
  ------------------ ------
  ---------------
---

3. 指定 Last-Modified

Last-Modified 表示资源最后一次修改的时间,当客户端访问时,服务器会将这个时间和客户端提供的 If-Modified-Since 字段进行比较,如果一致,则返回 304 Not Modified。和 ETag 一样,如果我们没有设置 Last-Modified 或者 Last-Modified 不正确,就会导致每次请求都返回 200 OK。

我们可以通过如下代码来设置 Last-Modified:

示例代码

下面是一个使用 ETag 的完整示例代码:

-- -------------------- ---- -------
----- ------- - -------------------
----- --- - ----------
----- ---- - -----

-------------------- ----- ---- -- -
  ----- ---- - -
    ----- -------
    ---- --
  --
  ----- ---- - -------------------------------------------------------------------------------
  --------------------------- ------------
  ------------------ ------
  ---------------
---

---------------- -- -- -------------------- --- --------- -- ---- ------------

总结

通过本文的介绍,我们了解了调用 app.get() 一直返回 304 Not Modified 的原因以及解决方法。为了避免这个问题,我们需要正确设置缓存的类型、过期时间、ETag 和 Last-Modified 头信息。在重要的接口上,可以使用 ETag 和 Last-Modified 来进行缓存,可以有效减少网络传输时间,提高性能。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/646d7b2b968c7c53b0c27252

纠错
反馈