HTTP/2推送进行时触发同资源GET请求的规范与浏览器实际行为问询
HTTP/2推送进行中时触发GET请求的行为:规范与浏览器实现
这是个非常细节且实用的问题,涉及HTTP/2推送的核心交互逻辑和浏览器缓存的底层优化,咱们一步步拆解清楚:
先明确你的场景
- 时间点0:客户端发起
GET /请求获取主文档,服务器同时主动推送/data.json资源 - 时间点1:主文档加载完成的脚本触发
GET /data.json请求,此时服务器的推送流尚未完成
规范定义的行为
HTTP/2的官方规范(RFC 7540)针对这种场景给出了明确的处理原则:
当客户端发现有一个正在进行的推送流对应自己即将发起请求的资源时,客户端可以发送
RST_STREAM帧终止该推送流,转而处理自己主动发起的请求;或者也可以选择继续接收推送,同时忽略自己的请求。
规范并没有强制要求必须合并请求,但核心目标是避免客户端重复接收同一资源,给了客户端灵活处理的空间。
浏览器的实际处理(以Chromium为例)
现代浏览器(比如Chromium内核的Chrome、Edge等)都会做更智能的优化,不会让同一资源出现并行的网络请求,核心依赖的是HTTP缓存的单写多读锁机制:
- 当服务器的推送流开始向浏览器缓存写入
/data.json时,缓存会为这个资源加上一个「写锁」,确保同一时间只有一个写入操作 - 此时脚本触发的
GET /data.json请求会先检查缓存状态,发现有正在进行的写入操作,就会进入等待队列,而不会向服务器发起新的请求 - 如果推送顺利完成,等待的请求会直接读取缓存中的资源;如果推送中途失败(比如服务器中断推送),浏览器才会重新发起网络请求去获取资源
核心问题:会不会发起两次请求?
结论是:现代浏览器不会发起两次请求。
虽然规范没有强制要求合并,但主流浏览器都通过缓存锁这类机制做了优化,确保同一资源不会同时存在推送流和主动请求两个并行的网络操作。只有在推送完全失败且缓存无数据的情况下,才会触发主动请求。
内容的提问来源于stack exchange,提问作者Nick Russler
相关产品推荐
相关产品推荐

