服务器响应如何正确匹配对应的待处理AJAX请求?
同连接并发AJAX请求的响应路由匹配规则
浏览器不需要依赖HTTP/1.1的自定义业务头部字段区分响应,匹配逻辑完全由浏览器网络栈的队列管理、HTTP协议本身的固有规则实现,你感知到的“两个激活请求在同一条连接上等待响应”,只是JavaScript运行时暴露的上层错觉。
具体分场景拆解逻辑:
- HTTP/1.1 持久连接场景
HTTP/1.1本身没有多路复用能力,主流浏览器默认也早已禁用了兼容性极差的HTTP管线化(Pipelining)技术,因此同一条TCP持久连接上的请求严格遵循「发送一个完整请求→接收完对应完整响应→连接释放为空闲状态→发送下一个请求」的串行规则。
你在JS层先后发起1号、2号AJAX请求时,两个请求的回调确实都会被挂起等待,但网络栈会先把1号请求推入连接的发送队列,等1号请求的响应完整接收、和1号请求的处理程序绑定回调执行完成后,才会把2号请求通过同一条连接发出去。这种模式下响应顺序和请求发送顺序严格一一对应,根本不存在匹配错误的可能。
你平时观察到的同域下6个左右的并发请求,本质是浏览器为同一个域名维护了多个独立的TCP连接池,每个连接各自串行处理请求,不同连接的套接字本身就可以作为区分标识,哪个套接字收到响应,就匹配对应连接上当前正在等待响应的那个请求即可。 - HTTP/2、HTTP/3 多路复用场景
这两个版本的HTTP协议才真正支持同一条连接上并行发送多个请求,协议帧层专门设计了流ID元数据:每个请求发起时会被分配一个全局唯一的二进制流ID,该请求的所有请求帧、服务器返回的对应响应帧都会携带同一个流ID。这个ID存在于协议帧的二进制头部,不属于HTTP明文请求头的范畴,因此你在开发者工具的头部面板里看不到。浏览器收到响应帧时,直接读取帧上的流ID,就能精准找到绑定了对应ID的AJAX事件处理程序,完全不会出现错配。
补充说明:很多人误以为调用
xhr.send()或者触发fetch之后请求就立刻发出去了,实际上请求可能只是被放进了浏览器的待发送队列排队,等对应连接空闲才会真正写入网络。只要请求还没真正写入网络链路,就不算在连接上处于“等待响应”的状态,自然也不会出现两个请求同连等响应导致响应乱序的问题。
内容的提问来源于stack exchange,提问作者Fixee
相关产品推荐
相关产品推荐

