2

我有一个 api,它返回一个对象作为响应,以及一个 etag 和 max age 作为标题。响应如下所示:

标题:

  'x-frame-options': 'SAMEORIGIN',
  'x-xss-protection': '1; mode=block',
  'x-content-type-options': 'nosniff',
  'x-download-options': 'noopen',
  'strict-transport-security': 'max-age=15778476000; includeSubDomains',
  'access-control-allow-origin': '*',
  etag: 'c69148a0489a95058e729bde7fd4bf32bf2077b1cba8d4fcf0c2da6e696fa33e',
  'cache-control': 'private,max-age=43200' 

身体:

{
id: 1985,
url: "https://example.com",
...
}

所需的场景是一个 android 应用程序发出请求以请求此数据。Api 返回数据以及 43200 秒的最大年龄。

如果在 43200 秒过去之前发出请求,则应用程序会缓存上一个响应中的数据。应用程序仍然发出请求,后端服务编译响应数据,使用请求的 etag 来确定响应数据是否已更改。如果数据已更改,则返回 200 http 状态和数据。否则返回 403 状态并且没有数据。

应用程序接收响应。它使用快速网络来处理缓存(我的安卓队友说)。如果返回 200 状态代码,则更新数据。否则,应用程序会保留旧数据。

如果在 43200 秒过后发出请求,则应用程序不再有缓存的响应或它的 etag。发出请求,即使数据中没有任何变化,数据也被视为“新”,状态码 200 与上面的 max-age 标头一起返回。

实际发生的情况:

由于某种原因,在处理完第一个请求并且应用程序接收到数据后,直到 43200 秒过去才发出请求。android 开发人员说他们看到发出请求并返回 0 字节,但是当我在服务器中监视请求时,我没有看到任何针对此 API 的请求。

这没有意义,因为 max-age 并不意味着没有请求。它只是指示应用程序在持续时间内将数据保留在缓存中。

我是否错过了缓存、etags 和 max-age 如何工作的想法?

后端内置在node js中,使用express进行路由。

4

1 回答 1

1

您只在标题中设置了max-ageandprivate指令。Cache-Control您描述的实际行为是正确的行为,因为max-age指令与每次发出请求时强制缓存验证响应无关。为此,您还必须将no-cache指令添加到Cache-Control标题中。

这些no-cache指令告诉缓存在服务之前始终使用源服务器验证存储的响应(即,您描述的所需行为)。重新验证后,存储的响应将再有效 43200 秒 ( max-age)。如果没有该no-cache指令,HTTP 客户端可以自由地使用缓存的响应。我猜这就是为什么您的朋友说请求已发出,但返回了 0 个字节(浏览器还显示缓存提供的响应为 0 个字节)。这也是为什么您没有观察到对服务器的任何传入请求的原因。

查看 Google 的这篇文章,了解有关 HTTP 缓存的一个很好的概述: https ://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching

如果您需要有关如何从缓存构造响应的详细信息,请查看 RFC7234 规范:https ://www.rfc-editor.org/rfc/rfc7234#section-4

于 2018-06-16T19:01:00.810 回答