在 notes使用web预览时提示服务器http通讯无法使用_应用层HTTP协议详解 - 跟小智一起学网络(5)...

前言

哈喽,小伙伴们,大家好,我是小智。

前面的准备工作都做好了,现在我们就要真正开始学习网络协议知识了。

在上一章节中,我们使用 Wireshark,简单分析过访问世界上第一个网站 http://info.cern.ch(后面简称 cern 网站)的 HTTP 报文,不过这个分析太过于简单。由于 HTTP 使用得非常广泛,在互联网公司面试中,HTTP 也被经常问到,所以我们有必要比较系统的来学习一下它。

这个章节包含的内容如下:

c7367922506201f43b8e002c19543822.png

正文

HTTP是什么

HTTP,全称HyperText Transfer Protocol,中文名称为超文本传输协议。

单从名字上来看,我们基本可以确定它是一个传输超文本的网络协议。那这里有三个问题:

传输: 是从哪里传输到哪里?

HTTP 是在浏览器(客户端)和网站(服务器)之间传输数据,它是一种双向传输。

超文本:什么是超文本?

超文本包含的内容非常广泛,文本、图片、音频、视频和动画等等这些多媒体信息,都属于超文本。

协议: 它是哪个层次的协议,基于的下层协议是谁?

HTTP 是应用层的协议,使用 TCP 作为传输层支撑协议,默认端口号是80。

简单回答了这三个问题,现在我们可以解释 HTTP 是什么了?

HTTP 是一个应用层的协议,它定义了浏览器(客户端)访问网站(服务器)的数据格式和规则,即浏览器客户端如何请求资源,网站服务器如何响应请求,并将资源发送给浏览器。当然,这里的资源指的就是超文本。

这么一说,大家是不是就不觉得陌生了呢?因为我们每天通过浏览器上网,都是使用的 HTTP 协议。我们在浏览器中输入网站的地址,浏览器向网站发起资源请求,网站将网页内容的超文本信息发送给浏览器,浏览器解析内容之后进行渲染,最终展现给我们的就是这个网站的内容。

8716339dace1ef0e89a65338748143df.png

HTTP的关键要素

URL

前面说到,浏览器发起的是对web服务器上资源的访问,互联网上有很多这样的服务器,对应的资源是海量的,那我们如何标识这些资源呢?简单来说,就是服务器如何确定浏览器是要访问自己,并且需要请求的具体是哪个资源。

为了在网络当中标识资源的唯一性,我们给资源了定义了一个格式统一而且唯一的网络地址,这个网络地址称为 URL(Uniform Resource Locator),即统一资源定位符。URL 由三部分组成:协议类型、存放资源的主机域名或者 IP 地址、主机提供服务的端口、资源目录、资源文件名,格式为:协议类型://<主机域名或IP地址>:<端口>/<资源目录>/<资源文件名>

3f1082d8715f7a572f29f58b1b03673d.png

协议类型表示我们通过什么协议访问资源,常用的协议类型有 ftp 、http 和 thunder 等等,我们现在讲的就是通过 HTTP 来访问web服务器的资源。

主机域名或 IP 地址是Web服务器在网络上的标识,每个Web服务器都有自己特有的域名或者唯一的IP地址。用户要访问某个资源,一定要先确定资源所在服务器的域名或者 IP 地址。比如小智想要访问世界上第一个网站,就在浏览器中输入它的域名 http://info.cern.ch。

对于端口,一般标准的应用层协议都给它分配了一个固定端口,如果服务器使用了这个固定端口,在浏览器输入 URL 时就可以不用包含。比如,HTTP 默认使用固定端口号 80,cern 网站使用的就是 80 端口,所以我们访问它的 URL 就可以省略端口。

资源目录指的是资源在Web服务器上的存储路径,服务器上资源的管理跟我们使用的电脑管理文件的方式非常类似,采用的都是树状的文件夹的方式,服务器有很多很多的目录,每个目录又可以包含各种目录以及资源文件,如果不指定路径或者指定的为"/",用户访问的就是服务器的首页,也就是服务器资源目录的根目录。

比如小智访问网页 http://info.cern.ch/hypertext/WWW/TheProject.html, 就是访问域名为 http://info.cern.ch 的Web服务器上 hypertext 目录下 WWW 目录中的的 TheProject.html 文件。

99de305fd272cf584d3465dcc8cc35da.png

方法

对服务器的资源进行地址唯一标识只是完成了第一步,现在浏览器可能会对资源进行不同的操作:

  • 比如小智在网上搜索资料,只是想查看下服务器上资料的内容;
  • 比如Web服务器想验证小智的身份,需要小智提交自己的账号密码;
  • 比如小智上传了一个文档到服务器,现在想要删除掉;

所以,Web服务器还得知道浏览器具体想对资源进行什么类型的操作,以便做出对应的回应。为了规定浏览器对资源的操作类型,HTTP 定义了相应的操作方法,小智这里整理出了一张表,包含了每种方法对应的含义以及它的使用场景:

3488d2e6774d30d809ed2bc390cdcb40.png

状态码

浏览器发起资源请求后,Web服务器并不是每次都会响应成功,出现的问题可能各种各样:

  • 比如要访问的资源已经被删除,不存在了;
  • 比如用户没有权限访问;
  • 比如服务器开了小差,无法响应;

这些情况下,服务器该如何通知浏览器呢?这个时候,就该 HTTP 的状态码上场了。状态码,简单理解就是浏览器客户端和服务器之间,定义的一个通用的有含义的代号。服务器每次回应时,把这个代号带上,浏览器就能很清楚的知道服务器的响应状态了。当然,为了让大家很清晰的知道每个状态的含义,每个状态都有一个对应的简短描述,我们叫它原因短语。

HTTP 状态码由三位十进制数字组成,第一位表示状态码的类型。HTTP 状态码分为五大类:

2feffe99c94643d7ad7d8a714d367aa9.png

常用状态码如下:

1xx 提示性状态码

100 Continue」已收到请求的初始部分,请客户端继续。

101 Switching Protocols」服务器正在根据客户端的请求切换协议,只能切换到HTTP 更高版本的协议。

2xx 成功状态码

200 OK」表示请求成功,客户端的请求已被正常处理。

201 Created」表示请求已被正常处理,服务器创建了新的资源,比如用在对PUT方法创建文件的响应。

202 Accepted」表示已经接受请求,但未处理完成。

204 No Content」表示请求已被正常处理,与200 OK 不同的是,响应消息不包含数据内容。

206 Partial Content」表示客户端发起的是范围请求,只请求资源的一部分,服务器已经正常响应这次请求的数据,常应用于 HTTP 分块下载或断点续传,

3xx 重定向状态码

301 Moved Permanently」表示永久重定向,请求资源的URL已更新,以后需改用新的 URL 访问,响应头里 Location 字段携带有URL,浏览器会自动跳转。

302 Found」表示临时重定向,请求的资源还在,暂时需要用另一个 URL 来访问,将来的请求仍然使用老的URL,响应头里 Location 字段携带有URL,浏览器会自动跳转。

303 See Other」表示请求的资源存在另外一个URL,客户端用这个URL去请求。

304 Not Modified」所请求的资源未修改,服务器返回此状态码时,不会返回任何资源,常用于缓存控制。

4xx 客户端错误状态码

400 Bad Request」表示客户端发送了一个错误的请求。

401 Unauthorized」表示需要客户端进行身份认证。

403 Forbidden」表示访问请求被服务器拒绝,并且通常服务器不想告诉客户端被拒绝的原因。

404 Not Found」表示在服务器上无法找到请求的资源,无法提供给客户端。

405 Method Not Allowed」表示服务器不支持客户端对资源的请求方法。

408 Request Timeout」表示由于等待客户端发送请求的时间过长,服务器关闭连接。

5xx 服务器错误状态码

500 Internal Server Error」表示服务器内部发生了错误,无法处理请求,但具体发生了什么错误,我们并不知道。

501 Not Implemented」表示服务器不支持客户端请求的功能。

502 Bad Gateway」表示服务器自身工作正常,访问后端服务器发生了错误,通常是服务器作为网关或代理时返回的错误码。

503 Service Unavailable」表示服务器当前很忙,暂时无法响应客户端的请求。

505 HTTP Version Not Supported」表示服务器不支持请求的HTTP协议版本,无法处理请求。


HTTP报文

HTTP的协议交互过程,就是一个资源请求和应答的过程。从数据报文来看,HTTP报文可以分为两类:请求报文和响应报文。浏览器客户端发出的报文为请求报文,服务器发出的报文为响应报文。

请求报文

请求报文分为请求行、首部字段和主体(HTTP 要传输的内容)三部分。其中首部字段又分为请求首部字段、通用首部字段和主体首部字段。另外,主体部分可以没有,比如 GET 请求报文就没有主体部分。

a5ff2f3ae4e9b1be1680639743a35cfe.png

响应报文

响应报文分为状态行、首部字段和主体(HTTP 要传输的内容)三部分。其中首部字段又分为响应首部字段、通用首部字段和主体首部字段。

6977f242bd2a0d42b469f88a59c2fdbb.png

报文交互过程

为了更实际的了解 HTTP 的报文结构以及交互流程,我们通过 curl 工具抓取访问http://info.cern.ch/hypertext/WWW/TheProject.html 页面的 HTTP 报文来分析一下。具体抓包步骤在上一章节咱们已经讲过,这里不再赘述。

打开抓取到的 HTTP 报文,进行 IP 地址过滤后,可以看到访问网页的 HTTP 报文交互流程:

f271fd1034fa54b64a39ae8703905340.png

首先是 TCP 建立连接的三次握手,接着 curl 客户端发起 HTTP GET 请求,然后服务器回应HTTP 200 OK,最后 TCP 四次挥手结束连接(这里抓到的包,其实服务器还没有发起 FIN 包来结束连接),正常访问流程就结束了。

271a7562d56b573fff1dc5721fc827bd.png

在 HTTP 的早期版本,使用的是短连接的方式,就是服务器每次连接只处理一个请求,处理完即断开连接。这种方式在资源请求频繁的场景下,比如浏览器打开一个有很多资源类型的网页,会发起很多次请求,每次请求就都需要重新发起 TCP 连接,从而影响传输性能,也增加了服务器的处理开销。在 HTTP 1.1 版本中,默认都采用了持久连接的方式,通信任何一方没有提出断口连接,即保持连接状态,以便下次进行资源请求。

c24c70bb5f11d55550f64e471efe2fac.png

现在我们想清晰的看到HTTP请求和响应的具体内容,就要用到Wireshark追踪流的功能,流追踪功能首先选中这条流的某个报文,然后右键,点击追踪流选项的HTTP流,像下图这样:

06f23cce31be3d1a9ecfd547e8fa41d7.png

这里说明一下报文流的概念,流也称为一个会话或者一次连接,就是源IP、源端口、目的IP、目的端口和传输层协议号这五元组完全一样(报文交互是双向的,源和目的可以互换)的一组报文,浏览器打开一个网页,会有一条或者多条流。

对我们抓取的HTTP报文进行流追踪后,可以看到:

4509a464bbe43bdcbc76cc8f5cbbd58a.png

怎么样,通过Wireshark对报文的分析,HTTP 报文的结构是不是看起来就一目了然了呢?

首部字段

方法、URL和状态码我们都已经讲过了,现在轮到 HTTP 中非常重要的首部字段了。综合 HTTP 的请求报文和响应报文的首部字段,首部字段分为四种,即通用首部字段、请求首部字段、响应首部字段和主体首部字段。

通用首部字段

通用首部字段指的是请求报文和响应报文都会使用到的首部字段,它提供与报文相关的最基本的信息。常用的通用首部字段如下:

  • Date: HTTP报文的创建日期和时间。
  • Connection: 用于指定客户端和服务器间的连接关系,例如 Connection:close,表示客户端或者服务器要断开连接,如果 Connection:Keep-Alive,就表示要继续保持连接。

请求首部字段

请求首部字段指的是只在请求报文中使用到的首部字段,用于补充请求的附加信息和客户端信息。常用的请求首部字段如下:

  • Accept: 客户端能接受的数据类型,例如 Accept: text/html,表示客户端支持 text/html 数据类型。
  • Accept-Charset: 客户端能接受的字符集,例如: Accept-Charset:UTF-8,表示客户端支持 UTF-8 编码。
  • Accept-Encoding: 客户端告能接受的内容编码,例如:Accept-Encoding: gzip,表示客户端支持 gzip 压缩。
  • Accept-Language: 客户端能接受的语言类型,例如:Accept-Language: zh-cn,zh,表示客户端支持中文。
  • Host: 用来指定要访问的服务器的域名,例如:Host: info.cern.ch,表示客户端访问域名为 info.cern.ch 的服务器。
  • User-Agent: 客户端发起请求的浏览器类型,例如:User-Agent: curl/7.61.1,表示发起浏览器请求的是curl,版本是7.61.1。
  • Referer: 客户端发起的请求来源于哪个URL,例如:Referer: http://info.cern.ch/,表示发起的请求来源于 http://info.cern.ch/ 这个网页。
  • Cookie: 用于服务器对浏览器客户端的识别和状态管理,它与响应首部字段 Set-Cookie 配合使用,客户端进行请求认证后,服务器在响应报文里面使用 Set-Cookie 字段为客户端分配一个唯一的Cookie值,浏览器会保存这个Cookie,下次访问服务器时会在请求报文中携带Cookie字段,服务器就可以识别这个客户端。

响应首部字段

响应首部字段指的是只在响应报文中使用到的首部字段,用于补充响应的附加信息和服务器信息。常用的响应首部字段如下:

  • Location: 配合 HTTP 3xx 重定向状态码使用,服务器告诉客户端通过这个新的 URL 访问资源,例如:Location:http://info.cern.ch/hypertext/WWW/TheProject.html,表示客户端需要去这个新的URL访问资源。
  • Server: 服务器的应用程序信息,例如:Server: Apache,表示服务器使用的应用程序是Apache。
  • Set-Cookie: 与请求首部字段 Cookie 对应,用于服务器对客户单的识别和状态管理。

主体首部字段

主体首部字段指的是请求报文和响应报文中主体部分使用的首部字段,用于补充内容的更新时间和主体相关信息。常用的主体首部字段如下:

  • Content-Type: 说明主体内容的数据类型和字符集,与请求首部字段的 Accept 和 Accept-Charset 对应,例如 Content-Type: text/html; charset=UTF-8,表示主体内容数据类型为 text/html,字符集为 UTF-8。
  • Content-Encoding: 说明主体内容的内容编码方式,与请求首部字段的 Accept-Encoding 对应,例如 Content-Encoding: gzip,表示主体内容的编码方式是 gzip。
  • Content-Language: 说明主体内容使用的语言类型,与请求首部字段的 Accept-Language 对应,例如 Content-Language: zh-CN, 表示主体内容的语言类型是中文。
  • Content-Length: 说明主体内容的长度,单位为字节,比如 Content-Length: 1000,表示主体内容的长度是1000字节。
  • Content-MD5: 服务器对主体内容进行MD5加密之后的值,客户端收到主体内容后,对主体内容进行 MD5 计算之后与 Content-MD5 的值进行比较,用于校验主体内容的完整性。
  • Allow: 说明服务器能支持的对资源请求的 HTTP 方法,与 HEAD 请求对应,例如 Allow: GET,HEAD,表示服务器支持对资源进行 GET 和 HEAD 请求。
  • Last-Modified: 说明资源最后被修改的时间,例如: Last-Modified: Thu, 03 Dec 1992 08:37:20 GMT。
  • Etag: 表示主体内容的标识,服务器会为每份资源分配唯一的 Etag 值,例如同一网页的中文版和英文版的URL相同,但是 Etag 不同。

HTTP的优缺点

HTTP 的关键内容,小智差不多就讲完了,现在咱们一起总结一下 HTTP 有哪些优点和缺点:

优点

1)使用简单:浏览器请求资源时,只需要传送操作方法和资源路径,头部内容采用灵活的key-value形式。

2)跨平台:与平台和开发语言无关,可以跨平台运行。

3)应用广泛:能够传输文本、图片、音频、视频和动画等各种资源类型,可以被广泛应用于各种场景。

4)易扩展: HTTP的方法、状态码和首部字段都可以根据实际需要进行自定义扩展。

缺点

1)无状态:服务器对于事务处理没有记忆能力,不知道客户端是什么状态。即我们给服务器发送 HTTP 请求之后,服务器根据请求,会给我们发送数据过来,但是服务器发送完不会记录任何信息。虽然这样服务器处理请求简单,可以减少服务器资源的占用,但是在某些场景下,显然不能满足客户端用户的需求,比如用户登录了网站之后在各个页面跳转,显然不可能访问每个网页都进行登录一遍。

当然,针对无状态的问题, HTTP 在 1.1 版本中使用 Cookie 技术进行了优化,使得服务器能识别客户端,并记住客户端的状态。

1e5cfce2d56d85262289d1efaa4e25cc.png

2)不安全:HTTP 最大的缺点应该就是,它采用明文传输通信内容导致的不安全性,主要表现在:

  • 明文传输内容,信息可能会窃听,比如我们登陆网站的账号密码,可能被不法分子轻易截获;
  • 无法验证通信双方身份的真伪,可能会被伪装欺骗,比如我们可能被欺骗,导致访问假冒的购物网站;
  • 无法验证数据的完整性,传输内容会被篡改,比如我们打开网页时,被恶意植入广告;

针对 HTTP 明文传输的不安全性问题,越来越多的服务器采用了加密的 HTTPS 协议来传输数据,关于 HTTPS 的实现机制,小智后面会单独做深入的分析。


HTTP的版本演进

在请求报文的请求行中,还有一个 HTTP 的版本字段,我们也来简单了解一下 HTTP 的版本演进历史。 HTTP 分为 0.9、1.0、1.1、2.0和3.0,共五个版本,其中 1.1 版本是现在主流使用的版本

HTTP/0.9

HTTP 的第一个版本,功能过于简单,只支持 GET 请求方法,只能传输文本信息,无法满足需求。

HTTP/1.0

报文必须包含 HTTP 头信息,请求行中需要指定 HTTP 的版本;

增加支持 POST 和 HEAD 方法;

根据首部字段 Content-Type 字段,可以支持多种数据类型的传输;

但是 HTTP 1.0 是短连接的方式,每次请求完成,需要重新发起 TCP 连接过程,性能很差。

HTTP/1.1

引入持久连接机制并被默认采用,多个请求可以共用一个 TCP 连接;

增加支持PUT、PATCH、OPTIONS 和 DELETE 方法;

增加支持断点续传;

支持管道方式,同一连接下多个请求可以同时发送,提高传输速度,比如浏览器向要发起 A 和 B 两个请求,发送 B 请求时,不用等到 A 请求的回应到达时才发送,而是可以将 A 请求和 B 请求同时发送。 需要说明的是,这里只是说浏览器可以同时发送请求,但是服务器还是按顺序处理请求的,所以请求的响应速度还是取决于服务器串行处理请求的能力

HTTP/2.0

增加双工模式,一个 TCP 连接里,不仅客户端可以同时发送请求,服务器也可以同时并行处理请求;

引入头部压缩机制,使用gzip等方式压缩 HTTP 头部信息,提高带宽使用率;

头信息和数据体不再是文本信息,而是使用二进制;

允许服务器主动向客户端发送资源,即服务器推送(server push)。

HTTP/3.0

基于 Google 的 QUIC协议,底层使用 UDP 进行数据传输,上层仍然使用 HTTP 2.0,所以相对于 HTTP 2.0,HTTP 3.0 最大的不同应该是 UDP 和 TCP 之间的不同,就是 UDP 采用的是无连接传输。


总结

好了,小伙伴们,HTTP 相关的内容到这里就要告一段落了,让我们一起再来回顾一下这个章节所讲的内容吧:

首先,我们了解了 HTTP 是什么,知道它是在浏览器客户端和服务器之间传输超文本资源的一种应用层协议,它使用非常广泛,我们每天通过浏览器上网都会使用到它;

接着,我们分析了 HTTP 通信需要的三个关键要素:URL用来唯一标识网络上的各种资源,方法用来确定对资源的操作类型,状态码用来告知资源操作的结果,三个要素缺一不可;

然后,我们通过实际环境抓取 HTTP 报文,对 HTTP 报文的结构和交互流程进行了详细分析,另外,报文中涉及到非常重要的首部字段,所以我们把常用的首部字段都梳理了一遍;

再接着,我们总结了一下HTTP的优点和缺点,HTTP 使用广泛,优点很多,但是最大的缺点就是明文传输,导致信息容易被窃取和篡改;

最后,我们了解了一下 HTTP 的版本历史,发现 HTTP 一直在改进迭代,希望让自己变得更完美。

在下一章节,我们将学习应用层的 DNS 协议。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值