HTTP协议的介绍以及相关概念

简单的介绍了HTTP协议的相关概念。


HTTP(Hypertext Transport Protocol)协议,即超文本传输协议,HTTP协议详细规定了浏览器和万维网服务器之间互相通信的规则,是一个应用层协议。 所谓“超文本(Hypertext)”,就是在纯文本(普通文字)的基础上添加了图片、视频、音频、超链接等,超出了文本的范畴,这样的文本就是超文本。超文本使用HTML(Hypertext Markup Language)即超文本标记语言来描述和展示!

请求访问文本或图像等资源的一端称为客户端(比如浏览器),而提供资源响应的一端称为服务器端。简单的说,HTTP就是一个通信规则,规定了客户端发送给服务器的内容格式,也规定了服务器发送给客户端的内容格式。

我们绝大多数的Web应用都是基于HTTP来进行开发的,我们对Web的操作也都是通过HTTP协议来进行传输数据的。可以说,Web是建立在 HTTP 协议上通信的,而普通程序员在进行Web应用开发时能够接触到的最多的协议就是位于应用层的HTTP协议,所以说HTTP协议对于普通程序员来说应该着重了解!

本文参考了《图解HTTP协议》,我建议学Java的都可以取看看这本书,非常简单!

1 HTTP不保存状态

HTTP 是一种不保存状态的协议,即无状态(stateless)协议。HTTP 协议自身不对请求和响应之间的通信状态进行保存。也就是说在 HTTP 这个级别,协议对于发送过的请求或响应都不做持久化处理。

使用 HTTP 协议,每当有新的请求发送时,就会有对应的新响应产生。协议本身并不保留之前一切的请求或响应报文的信息。这是为了更快地处理大量事务,确保协议的可伸缩性,而特意把 HTTP 协议设计成如此简单的。

可是,随着 Web 的不断发展,因无状态而导致业务处理变得棘手的情况增多了。比如,用户登录到一家购物网站,即使他跳转到该站的其他页面后,也需要能继续保持登录状态。针对这个实例,网站为了能够掌握是谁送出的请求,需要保存用户的状态。

HTTP/1.1 虽然是无状态协议,但为了实现期望的保持状态功能,于是引入了 Cookie 技术。比如,服务器把想要记住的信息通过Cookie 发送到客户端(浏览器),客户端将Cookie 保存在本地,下一次请求服务器的时候,就会自动带上这个Cookie ,服务器就能解析这个Cookie 获取相关信息,比如是否已登陆。有了 Cookie 再用 HTTP 协议通信,就可以在一定程度上管理会话状态了。

2 Cookie状态管理

保留无状态协议这个特征的同时又要解决类似不能保存用户登陆状态的矛盾问题,于是引入了 Cookie 技术。Cookie 技术通过在请求和响应报文中写入 Cookie 信息来控制客户端的状态。

Cookie 会根据从服务器端发送的响应报文内的一个叫做 Set-Cookie 的首部字段信息,通知客户端保存 Cookie。当下次客户端再往该服务器发送请求时,客户端会自动在请求报文中加入 Cookie 值后发送出去。

服务器端发现客户端发送过来的 Cookie 后,会去检查究竟是从哪一个客户端发来的连接请求,然后对比服务器上的记录,最后得到之前的状态信息。

没有 Cookie 信息状态下的请求:

在这里插入图片描述

第 2 次以后(存有 Cookie 信息状态)的请求:

在这里插入图片描述

上图展示了发生 Cookie 交互的情景,HTTP 请求报文和响应报文的内容如下:

请求报文(没有 Cookie 信息的状态):

GET /reader/ HTTP/1.1
Host: hackr.jp
*首部字段内没有Cookie的相关信息

响应报文(服务器端生成 Cookie 信息):

HTTP/1.1 200 OK
Set-Cookie: sid=1342077140226724; path=/;expires=Wed,10-Oct-12 07:12:20 GMT
Content-Type: text/plain;charset=UTF-8

请求报文(自动发送保存着的 Cookie 信息):

GET /image/ HTTP/1.1
Host: hackr.jp
Cookie: sid=1342077140226724

3 请求URI

HTTP 协议使用 URI 定位互联网上的资源。正是因为 URI 的特定功能,在互联网上任意位置的资源都能访问到。

当客户端请求访问资源而发送请求时,URI 需要将作为请求报文中的请求 URI 包含在内。指定请求 URI 的类型有很多,目前用得最广泛的就是URL,它是URI的一种实现方式,即通过资源的位置来定位资源!

但是目前,更倾向于将请求地址说成是URI,它是最准确的!

4 长连接和短连接

在HTTP/1.0中默认使用短连接。 也就是说,客户端和服务器每进行一次HTTP操作(一次请求),就建立一次连接,任务结束就中断连接。当客户端浏览器访问的某个HTML或其他类型的Web页中包含有其他的Web资源(如JavaScript文件、图像文件、CSS文件等),每遇到这样一个Web资源,浏览器就会重新建立一个HTTP会话。

而从HTTP/1.1起,所有的连接默认使用长连接,用以保持连接特性。使用长连接的HTTP协议,会在响应头加入“Connection=keep-alive”属性。

在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,客户端再次访问这个服务器时(多次请求),会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。

HTTP协议的长连接和短连接,实质上是TCP协议的长连接和短连接。HTTP的长连接(持有连接)和短连接本质上是TCP长连接和短连接。HTTP属于应用层协议,在传输层使用TCP协议,在网络层使用IP协议。 IP协议主要解决网络路由和寻址问题,TCP协议主要解决如何在IP层之上可靠地传递数据包,使得网络上接收端收到发送端所发出的所有包,并且顺序与发送顺序一致。TCP协议是可靠的、面向连接的。

实现长连接需要客户端和服务端都支持长连接,并且只要任意一端没有明确提出断开连接,则保持 TCP 连接状态。

4.1 管线化(pipelining)

HTTP1.1的长连接使得多数请求以管线化(pipelining)方式发送成为可能。 从前发送请求后需等待并收到响应,才能发送下一个请求。

管线化技术出现后,不用等待响应亦可直接发送下一个请求。这样就能够做到同时并行发送多个请求,而不需要一个接一个地等待响应了。

比如,当请求一个包含 10 张图片的 HTML Web 页面,与挨个连接相比,用持久连接可以让请求更快结束。而管线化技术则比持久连接还要快。请求数越多,时间差就越明显。

只不过,客户端还是要按照发送请求的顺序来接收响应。HTTP1.1的pipelining是默认关闭的。

5 HTTP协议的发展

5.1 HTTP1.0/HTTP1.1

  1. HTTP1.0默认是短连接,HTTP1.1默认长连接(持久化连接)。
    1. 在HTTP1.0默认是短连接,每次与服务器交互,都需要新开一个连接,每个连接都只能传送一个请求和响应,随后连接就会关闭。我们知道HTTP协议是基于TCP的,TCP每次都要经过三次握手,四次挥手,这就需要去消耗我们很多的资源的!
    2. HTTP1.1默认长连接(持久化连接)来解决这个问题,建立一次连接,多次请求均由这个连接完成!(但是如果某个请求或者响应阻塞了,还是会开新的TCP连接的)。长连接需要设置Connection = Keep-Alive 请求头。
  2. HTTP 1.1增加了host字段。 在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。
  3. HTTP 1.1中引入了Chunked transfer-coding ,范围请求,实现断点续传(实际上就是利用的HTTP消息头使用分块传输编码,将实体主体分块传输)。
  4. HTTP 1.1提出了管线化(Pipelining)理论。 客户端可以同时发出多个HTTP请求,不用按顺序等待前一个请求被响应之后再请求。但是这个pipelining仅仅是限于理论场景下,大部分桌面浏览器仍然会选择默认关闭HTTP Pipelining!所以现在使用HTTP1.1协议的应用,都是有可能会开多个TCP连接的!

5.2 HTTP2.0

HTTP Pipelining其实是把多个HTTP请求放到一个TCP连接中一一发送,而在发送过程中不需要等待服务器对前一个请求的响应;只不过,客户端还是要按照发送请求的顺序来接收响应!所以说。无论是HTTP1.0还是HTTP1.1提出了Pipelining理论,还是会出现阻塞的情况。从专业的名词上说这种情况,叫做线头阻塞(Head of line blocking)简称:HOLB,所以pipelining理论目前还是限于理论的阶段上,这个功能在基本上所有浏览器中默认还是关闭了的。

HTTP2.0与HTTP1.1最重要的区别就是解决了线头阻塞的问题!其中最重要的改动是:多路复用(Multiplexing)多路复用意味着线头阻塞将不再是一个问题,允许同时通过单一的 HTTP2.0连接发起多重的请求-响应消息,合并多个请求为一个的优化将不再适用(HTTP1.1中的Pipelining是没有付诸于实际的,之前为了减少HTTP请求,有很多操作将多个请求合并)。

6 基于HTTP的WebSocket

WebSocket,即 Web 浏览器与 Web 服务器之间全双工通信标准。其中,WebSocket 协议由 IETF 定为标准,WebSocket API 由 W3C 定为标准。仍在开发中的 WebSocket 技术主要是为了解决 Ajax 和 Comet里 XMLHttpRequest 附带的缺陷所引起的问题。所以说,WebSocket 是一种网络通信协议。

HTTP 协议有一个缺陷:通信只能由客户端发起,做不到服务器主动向客户端推送信息,而一旦 Web 服务器与客户端之间建立起 WebSocket 协议的通信连接,之后所有的通信都依靠这个专用协议进行。通信过程中可互相发送JSON、XML、HTML 或图片等任意格式的数据。

由于WebSocket是建立在HTTP基础上的协议,因此连接的发起方仍是客户端,而一旦确立 WebSocket 通信连接,不论服务器还是客户端,任意一方都可直接向对方发送报文。通常可以使用WebSocket协议实现在线网页聊天系统、各种客服系统等,因此WebSocket协议非常的重要,如果后续有高并发需求,那么可以使用Netty框架!这里简单的介绍WebSocket,后续我们会有专门的文章介绍WebSocket如何实现在线聊天系统!

6.1 WebSocket 协议的主要特点

  1. 推送功能:支持由服务器向客户端推送数据的推送功能。这样,服务器可直接发送数据,而不必等待客户端的请求。
  2. 减少通信量:只要建立起 WebSocket 连接,就希望一直保持连接状态。和 HTTP 相比,不但每次连接时的总开销减少,而且由于 WebSocket 的首部信息很小,通信量也相应减少了。

为了实现 WebSocket 通信,在HTTP连接建立之后,需要完成一次“握手”(Handshaking)的步骤:

  1. 握手-请求:为了实现 WebSocket 通信,需要用到 HTTP 的 Upgrade 首部字段,告知服务器通信协议发生改变,以达到握手的目的。

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

Sec-WebSocket-Key 字段内记录着握手过程中必不可少的键值。

Sec-WebSocket-Protocol 字段内记录使用的子协议。

子协议按 WebSocket 协议标准在连接分开使用时,定义那些连接的名称。

  1. 握手-响应:对于之前的请求,返回状态码 101 Switching Protocols 的响应。

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat

Sec-WebSocket-Accept 的字段值是由握手请求中的 Sec-WebSocket-Key 的字段值生成的。

成功握手确立 WebSocket 连接之后,通信时不再使用 HTTP 的数据帧,而采用 WebSocket 独立的数据帧。

在这里插入图片描述

参考:
《图解HTTP》

如有需要交流,或者文章有误,请直接留言。另外希望点赞、收藏、关注,我将不间断更新各种Java学习博客!

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘Java

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值