一个奇怪的站点,如何判断一个网站请求是否响应完毕?

今天遇到一个非常奇怪的站点

http://lianlunchang.com/

或者点击此处
该站点如果通过浏览器去访问则会一直在加载中,直到超时。但是浏览器会正常展示页面信息。小弟想知道如何来实现这类网站的原理。
请各位大大帮忙分析一下这类请求。
这里不涉及这个网站为什么会被拦截,请勿回复这个。我需要知道是为什么这个网站会一直加载,但是页面展示正常。以及如何来通过chrome扩展来判断这个请求是否完毕。
先说明一下这个网站奇怪的点。
一个正常的请求会在chrome的network里面直接展示出来状态以及网站内容大小,加载时间等。但这个网站很特殊。没有展示pending状态,tab栏一直在加载。页面却正常显示出来。且网络请求中并没有其他pending请求。

阅读 3.6k
2 个回答

浏览器不需要等待页面完全加载完才去渲染。

所谓的“页面加载”实质就是一个 HTTP 请求。HTTP 虽然是一个文本协议,但也是基于 Socket 流式传输的。既然是流式的,那服务端就完全可以先只发送一部分数据、但是却不关闭这个流,这样客户端会认为没有接收完而选择继续等待,直到超时。

当然了,这是对于 HTTP/1.1 之前(先忽略 Keep-Alive,它不是重点)。在 HTTP/2 有了多路复用之后,多个 HTTP 请求底下对应的可能是同一个 Socket,这样就不能单纯地把“Socket 关闭”和“响应接收完毕”划等号了 —— A 请求的响应接收完了、B 请求的响应可未必也完了,此时 Socket 并不会关闭。

幸好制订 HTTP 协议时早就考虑好了和底层协议脱钩的事情,它是有 Content-Length 这个响应标头的,它指示了响应体应该有的实际长度,那么当客户端接收到符合的长度后,就认为本次 HTTP 的响应已经接收完毕了。

那么反过来想,如果服务端返回了一个错误 Content-Length,比如返回了 100,但是响应体却只有 99,客户端就会认为本次请求还没结束,那么它就会接着等。

你可以用 Wireshark 之类的抓包看一下(需要直接抓 TCP,而不是 DevTools/Fiddler/Charles 这种基于 HTTP 的,因为如上文所言,这个 HTTP 报文会被认为是“不完整的”,所以这些基于 HTTP 的抓包工具是不能正确解析的),观察一下这个请求的实际收到的字节数是不是小于 Content-Legnth


回到问题本身,你在 JS 层面上无法判断的,因为浏览器本身屏蔽了底层 Socket 的细节。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏