企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
浏览器是如何访问互联网的呢? 首先人们会告诉浏览器一个网址,比如www.jd.com, 然后就可以通过TCP协议与服务器建立一个连接,通过这个连接通道给服务器发消息,消息格式是与服务器约定好了的。 服务器会按照约定返回整个页面的数据(HTML文档),当然也是通过**同一个**连接通道。 然后这个连接通道会被关闭。 浏览器与服务器的这种约定就叫**HTTP协议** ## 重复利用每个连接通道 随着互联网的发展,网页变得非常复杂,开始出现图片等,为了把图片得资源快速下载下来,需要通过TCP协议建立很多的连接通道,有些下载图片,有些下载CSS等。 我们知道TCP的连接提交的麻烦,需要3次握手和4次挥手。。 如果连接建立得较多,浪费极大。 那么能不能建立一个连接通道,并且不关闭? 可以协商出一个keep-alive机制,默认情况下,让TCP协议一直保持打开的连接通道,可以持续的在连接通道上发送消息。 如果长时间不发消息时,或者某一方明确要关闭连接,可以把连接通道关闭掉 这样,可以复用连接通道了。 ## 只有纯数据,不用格式化文档 随着页面越来越大,人们对响应时间要求越来越高,大家希望能迅速的看到效果。 但是每次服务器会返回HTML文档给浏览器,导致浏览器需要刷新整个页面。 观察发现,每次从服务器收到的数据其实只有一丁点的变化,能否进行局部更新呢? 也就是说,装载过HTML文档之后,后续的操作,就只通过XML或者JSON这种纯粹的数据进行交流了。 具体流程如下: 用户在页面操作之后,整个页面不会刷新(浏览器的地址不会改变),JavaScript在背后让TCP建立一个通道,和服务器通信,获取更新的数据,然后局部更新。 不过这还有一个问题,JavaScript在发出HTTP请求之后,需要等待服务器把数据返回,这段时间内,浏览器是什么都干不了的。就像假死了一样。 可以**异步**:JavaScript发出HTTP请求之后,不等待服务器把数据返回,立刻干别的事情去了。等到服务器的数据回来了,浏览器再通知他处理。这就是AJAX ## 抛弃HTTP 完全抛弃的HTTP是不可能的,但是在某些场景下,比如说把桌面应用迁移到浏览器上的时候。 假设现在有个在线协作软件,多个人可以在同一个页面进行操作,如果想把每个人的鼠标位置广播给大家,这就非常的麻烦。 因为会向服务器发送数据非常频繁,但是每次发送的信息又非常的少。类似于x=100&y=200这样的东西。 如果每次都遵循HTTP协议,构建HTTP请求,会发现传递了太多的无用的东西 ``` POST / HTTP/1.1 Host: localhost User-Agent: .... 略... Accept: text/html .... 略... Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip,deflate Keep-Alive: 300 Connection: keep-alive Referer: http://localhost/test.php Content-Type: application/x-www-form-urlencoded Content-Length: 9 x=20&y=70 ``` 而且在移动互联网时代,大家对实时性要求更高了,比如说股票信息、朋友圈更新等。 如果使用HTTP协议去经常**轮询**服务器,大部分时间是在做无用功。 能不能不局限HTTP协议呢? 大致总结一下: - 不要HTTP的头 - 浏览器和服务器之间要能互相发送数据 这不就是socket吗?两个电脑之间建立了socket之后,想发什么数据都可以,数据格式自己定义。 于是应用层的WebSocket就出现了。 但是HTTP被应用得太广泛了,防火墙、缓存、代理等都是基于HTTP的。为了让大家能迅速支持WebSocket,还需要和HTTP保持一定的兼容性, 比如建立WebSocket的时候,可以使用HTTP ``` GET /chat HTTP/1.1 Host: server.example.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== Origin: http://example.com Sec-WebSocket-Version: 13 ``` 这段话的意思是说:服务器,把 HTTP 升级为 Websocket 吧? 然后服务器回复: ``` HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= ``` 服务器回复:我同意,以后我们就切换到 Websocket 协议开始通信了啊。 于是连接就建起来了, 接下来浏览器和服务器就可以双向通信了。 浏览器要是想发送数据, 就直接发送 x=20&y=70, 根本没有浪费流量的 HTTP header , 服务器有啥数据想给我, 也直接推送, 不用我去查询了。 不过WebSocket也是基于TCP协议的,请示就是建立在原来TCP连接的通道之上。