0

是否有可能(没有请求的应用程序层缓存)在可缓存的情况下防止多次发送对同一资源的 HTTP 请求?如果是,如何?

例如,而不是

at time 0: GET /data (request#1)
at time 1: GET /data (request#2)
at time 2: received response#1 for request#1 // headers indicate that the response can be cached
at time 3: received response#2 for request#2 // headers indicate that the response can be cached

 

at time 0: GET /data (request#1)
at time 1: GET /data (will wait for the response of request#1)
at time 2: received response#1 for request#1 // headers indicate that the response can be cached
at time 3: returns response#1 for request#2

这将要求它可以在读取响应标头之前向浏览器指示响应将是可缓存的。请问有没有这样的机制。例如,带有某种前面的 OPTIONS 或 HEAD 请求。

4

2 回答 2

0

我的问题是,如果有一种机制可以向浏览器发出 URI 响应可以缓存的信号

是的,这就是Cache-control标题的作用。

并且对该 URI 的任何后续请求都可以返回任何正在进行的请求的响应......理想情况下,这将是 HTTP 规范的一部分

没有 HTTP 不会为您执行此操作,您需要自己实现缓存。这就是浏览器所做的。

我确实想检查是否已经有现成可用的东西

Javascript 库通常不支持缓存,因为 AJAX 请求通常是针对数据的,并且任何数据缓存通常发生在服务器上。我不知道任何库,当然要求 Js 库超出了 SO 的范围

于 2020-09-08T07:23:29.410 回答
0

根据浏览器的不同,如果可以缓存,第二个请求可能会被停止并提供服务,例如在 Chromium 中用于非范围请求:

缓存实现了单个写入器 - 多个读取器锁定,因此在任何给定时间只有一个对同一资源的网络请求在运行。 https://www.chromium.org/developers/design-documents/network-stack/http-cache

这是一个示例,其中三个并发请求仅导致单个服务器调用:

fetch('/data.json').then(async r => console.log(await r.json()));
fetch('/data.json').then(async r => console.log(await r.json()));;
setTimeout(() => fetch('/data.json').then(async r => console.log(await r.json())), 2000);

三呼

随后的请求传输了 0B 并且具有相同的随机数,表明只进行了一次服务器调用。

对于例如 Firefox,这种行为是不同的: Firefox 不会避免重复请求

想到的一个有趣的问题是,当对该资源的 H2 推送之前已启动但尚未完成时,会发生什么情况。

为了在这里重现测试代码: https ://gist.github.com/nickrussler/cd74ac1c07884938b205556030414d34

于 2020-09-09T11:44:56.460 回答