HTTP小册子(一)

403 阅读13分钟

一个人至少拥有一个梦想,有一个理由去坚强。心若没有栖息的地方,到哪里都是在流浪。 三毛

前不久把入门级的《图解HTTP》看完了,目前正在看《HTTP权威指南》,觉得很有必要把HTTP的基础知识总结出来,方便以后回顾。适逢中秋,幸甚至哉,故为之文~

诞生背景及历史:

背景

  互联网在诞生初期,它只属于少数人。在这一时期,有人便提出了让远隔两地的研究者们能共享知识的设想。

  最初设想的基本理念是:借助多文档之间的相互关联形成的超文本,连成可相互参阅的WWW(万维网)。

  为解决文本传输的难题,随之诞生了http协议(超文本传输协议)

发展历史

  1. HTTP/0.9 我们将正式版本1.0之前的http版本称之为0.9,只支持get请求,定义初衷是为了获取HTML对象。
  2. HTTP/1.0,正式作为标准被公布。添加了版本号和各种http首部以及对多媒体对象(图片、表格等)的处理,至今仍被广泛使用。
  3. HTTP/1.1(这里我将1.0+和1.1统称为HTTP/1.1),是当前使用最广的版本,新增特性包括持久的keep-alive连接、虚拟主机支持以及代理连接。同时该版本重点关注的是校正HTTP设计中的结构性缺陷,明确语义,引入重要的性能优化措施,包含对更复杂web应用和部署方式的支持。
  4. HTTP/2.0(HTTP-NG),主要是为了提升用户体验而做性能优化。当时的HTTP-NG工作组建议将HTTP组件模块化。可以看作是在应用层中增加了一个中间层并采用二进制连接协议,提供高性能、可拓展的远程调用方法支持;在传输报文时采用WebMUX协议,提高报文传输的性能;在应用层中提供更多功能和可拓展的接口。

TCP/IP

作为互联网最基本的协议——TCP/IP协议,是必须先了解的。

层次管理

按层次可将其分成应用层、传输层、网络层、链路层四个层。

  1. 应用层:决定了向用户提供应用服务时通信的活动,该层包括:HTTP协议、FTP协议、DNS服务。
  2. 传输层:提供处于网络连接中的两台计算机之间的数据传输。该层包括:TCP协议、UDP协议。
  3. 网络层:处理网络中流动的数据包。该层包括IP协议。
  4. 链路层:用来处理连接网络的硬件部分。

HTTP协议: 超文本传输协议,用于客户端和服务端之间的通信,通过请求和响应的交换达成通信。

TCP协议: 传输控制协议,提供可靠的字节流服务。
  字节流服务是指TCP收到数据流之后,将数据流切成以段为单位的数据块,并将数据块封装在IP分组中进行传输。
  那么是如何可靠地实现呢?这就得提下TCP的“握手”机制。
TCP的三次握手(建立连接)
第一次握手:客户端向服务端发送带有SYN标志的TCP报文,表示开始跟服务端建立连接;
第二次握手:服务端收到报文后,回传一个带有SYN/ACK标志的报文以示传达确认信息,表示同意建立连接;
第三次握手:客户端再回传一个带有ACK标志的报文,通知服务端TCP连接成功建立;
TCP的四次挥手(断开连接)
以客户端主动发起断开连接为例:
第一次挥手:客户端向服务端发送报文,示意将断开连接,并进入等待断开的第一阶段。
第二次挥手:服务端接收到客户端的报文后,给客户端返回报文,示意收到断开连接的消息,并进入等待断开阶段。
第三次挥手:服务端接等待阶段结束,向客户端发起报文。示意已做好断开的准备,此时服务端不再向客户端发送报文,但还能接收报文;客户端进入等待断开的第二阶段。
第四次挥手:客户端接收服务端的报文后,向服务端发起报文,示意已确认服务端做好断开的准备。服务端断开连接。 (以上只是我个人对四次挥手粗浅的描述,实在觉得书面描述过于让人头大)

IP协议:网际协议,通过Mac地址和IP地址的配对进行数据包的传送。

DNS服务: 提供域名和ip的解析服务,可通过域名查找ip或者逆向查找。

通信传输流

拿HTTP请求为例:
客户端作为发送端时,HTTP报文自上而下依次经过应用层、传输层、网络层和链路层,每经过一层HTTP数据都会带上该层的首部信息;
服务端作为接收端时,会以链路层至应用层的顺序接收到HTTP请求,每经过一层便会消去该层的首部信息

HTTP报文

一次完整的HTTP请求最重要的那便是在发送端和接收端之间携带数据流进行传递的请求、响应报文。

请求报文的结构如下:

响应报文的结构如下:

常用HTTP请求方法

GET: 从服务器获取数据
POST:向服务器发送数据
PUT:将请求的主体部分存放在服务器上
DELETE:从服务器上删除数据
TRACE:对可能经过代理服务器传送到服务器上去的报文进行跟踪
OPTIONS:决定可以在服务器上执行哪些方法
HEAD:只从服务器获取数据的首部

请求URI

URI指的就是统一资源标识符,也就是我们通常称的URL。
它有两种形式:

  1. URL: 统一资源定位符。它是HTTP请求中最常见的URI形式。
  2. URN: 统一资源名。它是作为特定内容的唯一名称使用的,与目前的资源所在地无关。(仍处于试验阶段)

三者关系:
URL和URN是URI的子集,URL是URN的大哥。

绝对URI格式举例:

请求状态码

状态码为客户端提供了一种理解请求处理结果的便捷方式,并被分成五大类:
一:100 ~ 199(信息性状态码),表示接收的请求正在处理当中;
二:200 ~ 299(成功状态码),表示请求正常处理完毕;
三:300 ~ 399(重定向状态码),表示需要进行附加操作以完成请求;
四:400 ~ 499(客户端错误状态码),表示服务器无法处理请求;
五:500 ~ 599(服务器错误状态码),表示服务器处理请求出错;

首部

首部和请求方法共同决定了客户端和服务器能做什么事情。我们可将首部分成五个主要类型:

  1. 通用首部: 客户端和服务器都可以使用的公共首部。例如:Date(报文构建时间)。
  2. 请求首部:请求报文特有的首部,给服务端提供客户端的信息,增加请求的限制条件以及安全机制。例如:Authorization(客户端认证信息) 。
  3. 响应首部:响应报文特有的首部,给客户端提供服务端的额外信息。例如Age(响应持续时间)。
  4. 实体首部:提供了有关实体及其内容的大量信息。例如:Content-Type(主体的对象类型)。
  5. 拓展首部: 应用程序开发者创建的首部,非标准。

首部信息数量庞大,个人觉得掌握常用的首部,并在开发过程中对需要的首部能查阅相关文档进行使用即可。

HTTP协议优缺点:

优点

  1. 不保存状态,更快速地处理大量事务;
  2. 持久连接节省通信量;
  3. 管线化技术出现后可并行发送多个请求。

缺点

  1. 通信使用明文(不加密),内容可能会被窃听;
  2. 不验证通信方的身份,有可能遭遇伪装;
  3. 无法验证报文的完整性,报文有可能已遭篡改。

我们可以通过加密处理来防止被窃听:
方法一:由于http没有机密机制,但可以通过和SSL(安全套接层)或TLS(安全传输层协议)的组合使用,来加密通信内容。
方法二: 对请求主体内容进行加密处理,这得要求客户端和服务端都事先知道加解密方法。

HTTPS就是SSL和HTTP的结合产物。

代理

代理也就是web代理服务器,作为客户端和服务端的“中间人”,它既可以扮演服务端的角色给客户端返回响应报文,又能扮演客户端的角色给服务端发送请求报文。

网关和代理类似;严格上来讲就是代理是同一协议的;而网关是跨协议的。

代理的优点

那么我们为什么要使用代理呢?这得益于代理具有以下优点:

  1. 改善安全性;我们可以通过设置安全防火墙,控制数据的流入流出以及对数据安全性进行检查。
  2. 提升性能: 为慢速web服务器设置反向代理,提升客户端对慢速服务器进行访问时的速度。
  3. 节省费用:设置web缓存,缓解网络瓶颈问题,不需要更多的带宽就能更快的加载页面。
  4. 监视流量并对其进行修改:设置内容转码器,可以修改内容的主体格式。例如对传输内容进行压缩;对呈现的网页进行语言的转换等...

代理分类一

正向代理
位于客户端和原始服务器之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。简言之正向代理代表客户端转发请求,为客户端服务。

反向代理
位于用户与目标服务器之间,但是对于用户而言,反向代理服务器就相当于目标服务器,即用户直接访问反向代理服务器就可以获得目标服务器的资源。简言之反向代理代表服务端返回响应报文,为服务端服务。

我们在开发中经常遇到跨域的问题,在vue项目中便可以通过设置反向代理解决这一问题。

代理分类二

缓存代理
首次转发响应时将资源的副本缓存再代理服务器上,再次接收相同请求时,可直接返回,不走目标服务器。

透明代理
转发请求或者响应时,不对报文做任何加工操作的代理类型

缓存

Web缓存(或HTTP缓存)是用于临时存储(缓存)Web文档(如HTML页面和图像),以减少服务器延迟的一种信息技术。

缓存的优点

  1. 减少了冗余的数据传输:重复性的数据如果对其进行缓存,以后用户再次请求时访问缓存即可,而不用再次对服务器进行访问。
  2. 缓解带宽瓶颈问题:在数据量较大的情况下带宽造成的传输时延越发明显,大部分网络本地带宽要大于异地传输的带宽。因此通过为本地网络设置缓存,用户可以就近快速获取资源,
  3. 降低对原始服务器的要求: 因为缓存分摊了服务器的压力,这样就避免了请求过载的情况出现,对服务器的要求自然也就降低了。
  4. 降低了距离时延:距离也是造成传输时延的原因之一,长距离的传输会加大时延,因此通过为本地网络设置缓存,用户可以就近快速获取资源。

缓存命中:
可以用已有的副本为到达缓存的请求提供服务。
缓存未命中:
到达缓存的请求由于没有副本可用而被转向服务器。
缓存再验证:
由于服务器上的资源可能发生变化,缓存得确保其副本和服务器上的资源是否一致。这种“新鲜度检测”则是缓存再验证。

缓存的处理步骤

一条HTTP GET报文的基本缓存处理过程分7个步骤:

  1. 接收:缓存从网络中读取抵达的请求报文;
  2. 解析:对报文进行解析,提取出URL和各种首部。
  3. 查询:查看是否有副本可用,无则向服务器获取并保存;
  4. 新鲜度检测:检查缓存中的副本是否新鲜的,不是则向服务器询问是否更新,如果更新则获取并保存
  5. 创建响应:用新的首部和已缓存的主体构建一条响应报文;
  6. 发送: 将响应报文返回给客户端;
  7. 日志:可选地创建一个日志文件来描述这个事务。

缓存的新鲜度校验

个人角度来看,我把缓存的新鲜度校验分成两个层面: 一是缓存层面;二是服务器层面。
只有缓存层面校验结果是不新鲜才会进入服务器层面的校验,因此缓存不用为每次请求都进行再验证。

缓存层面
就跟去超市买东西时,看商品的保质期是一个道理。
我们可以查看响应报文中携带的首部来确认是否是最新鲜的:
Cache-Control:max-age(定义了文档的最大使用期);
Expires(绝对的过期日期)

服务器层面
HTTP允许缓存向原始服务器发起一个“条件GET”请求,该请求会携带一些特殊的首部,服务器只有在文档和缓存中的副本不一致时才返回新的。


    以上就是我个人整理出来的一些比较基础的HTTP知识点吧,《权威指南》我还在看,后面还会再总结一篇,敬请期待~如果发现有错误还请联系我^_^

希望这篇文章能对你有所帮助~

扫码_搜索联合传播样式-白色版.png