防止对可缓存响应的重复 HTTP 请求

Prevent duplicate HTTP requests for cachable responses

是否有可能(没有请求的应用层缓存)在可缓存的情况下防止多次发送同一资源的 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

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

My questions is, if there is a mechanism to signal the browser that the response for URI will be cachable

是的,这就是 Cache-control headers 所做的。

and any subsequent requests for that URI can return the response of any in-flight request....Ideally this would be part of the HTTP spec

No HTTP 不会为你做这个,你需要自己实现缓存。这就是浏览器所做的。

I did want to check if there is already something ready ouf-of-the-box

Javascript 库通常不支持缓存,因为 AJAX 请求通常是针对数据的,而任何数据缓存通常发生在服务器上。我不知道任何图书馆,当然 asking for Js libraries is out of scope on SO.

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

The cache implements a single writer - multiple reader lock so that only one network request for the same resource is in flight at any given time. 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 并且具有相同的随机数,表明仅进行了一次服务器调用。

此行为与例如火狐:

我想到的一个 是当对该资源的 H2 推送已启动但尚未完成时发出资源请求时会发生的情况。

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