一、HTTP 简介

HTTP(Hyper Text Transfer Protocol,超文本传输协议)是一个用于传输超媒体文档(例如 HTML)的应用层协议,被设计用于 Web 浏览器与 Web 服务器之间的通信(但也可以用于其他目的),它通常基于 TCP/IP 协议传输数据。

简单来说就是客户端和服务端进行数据传输的一种规则。Web 使用 HTTP 协议作为规范,完成从客户端到服务器端等一系列运作流程。可以说,Web 是建立在 HTTP 协议上通信的。

二、与 HTTP 相关的协议:IP、TCP、DNS

  • TCP/IP 协议族

    TCP/IP 协议是互联网相关联的各类协议集合的总称。不同的网络间要相互通信,就是在 TCP/IP 协议族的基础上运作的,而 IP、ICMP、TCP、UDP、FTP、HTTP 等都属于它内部的一个子集。
    TCP/IP 协议族按层次分别分为以下四层:

    • 应用层
    • 传输层
    • 网络层(又名网络互连层)
    • 链路层(又名数据链路层,网络接口层)

  • 负责传输的 IP 协议 / IP 地址

    • IP 协议

      Internet Protocol 网络之间互连的协议,位于网络层。几乎所有使用网络的系统都会用到 IP 协议,它的作用是把各种数据传送给对方。

    • IP 地址

      IP地址是IP协议提供的一种统一的地址格式,它指明了每一个网络和每一台主机被分配到的逻辑地址。在同一个网络中,IP 地址具有唯一性。

      在 IP 协议中,IP 地址有两个版本

      • IPv4 网络使用32为地址,以点分十进制表示,如:192.168.0.1、常用于测试的本机地址127.0.0.1
      • IPv6 地址的128位(16个字节)写成8个16位的无符号整数,每个整数用四个十六进制位表示,这些数之间用冒号(:)分开,例如:3ffe:3201:1401:1280:c8ff:fe4d:db39:1984
      • 在 windows 下,可以通过 ipconfig 查看本机的 IP 地址
  • 确保可靠性的 TCP 协议

    Transmission Control Protocol 传输控制协议,用于从应用程序到网络的数据传输控制,是一种可靠的、基于字节流的传输层通信协议。
    TCP 负责在数据传送之前,将它们分割成以报文段为单位的 IP 数据报包,然后在它们到达的时候将它们重组。

    TCP 为了保证报文传输的可靠,采用了三次握手的策略来建立连接,握手过程中使用了 SYN(synchronize) 和 ACK(acknowledgement)的标志。

    三次握手的过程如图:

    1. 客户端首先发送带有 SYN(SEQ=x)报文的数据包给服务器端,进入SYN_SEND 状态。
    2. 服务器端收到 SYN 报文,回传一个 SYN (SEQ=y)/ACK(ACK=x+1)报文以示传达确认信息,进入SYN_RECV状态。
    3. 最后,客户端收到回传的 SYN/ACK 报文,再回应一个 ACK(ACK=y+1)报文,进入 Established 状态,代表握手结束。
    4. 三次握手完成,客户端和服务器端成功地建立连接,可以开始传输数据了。

    若在握手过程中的某个阶段莫名中断,TCP 协议会再次以相同的顺序发送相同的数据包,从而保证了数据可靠的传给对方。

  • TCP/IP 协议传输流程

    比如,我们想看某个 Web 页面,客户端在应用层发出一个 HTTP 请求。

    在每个分层中,都会对从上一层接收到的数据附加一个首部,在这个首部中包含了该层必要的信息,如发送的目标地址、协议的相关信息等。

    而接收端的服务器在接收到数据后,按序往上层发送,每经过一层时会把对应的首部删除,一直到应用层。当传输到应用层,才能算真正接收到由客户端发送过来的 HTTP 请求。

  • 负责域名解析的 DNS 服务

    DNS(Domain Name System)域名解析系统,位于应用层,它提供域名到 IP 地址之间的解析服务。

    好比我们去拜访朋友要先知道别人家怎么走一样,我们访问网页必须首先知道其地址,通常在浏览器中输入如:www.baidu.com 的域名来访问网页,而不是直接通过 IP 地址访问。

    在 Internet 上,域名与 IP 地址之间是一一对应的,虽然域名便于人们记忆,但机器之间只能互相识别 IP 地址,它们之间的转换工作称为域名解析。域名解析需要由专门的域名解析服务器来完成,DNS 就是进行域名解析的服务器。

    当我们在浏览器中输入域名并按下回车键时,域名通过 DNS 解析服务映射到 IP 地址之后访问目标网站,所以,当请求发送到服务器时,已经是以 IP 地址的形式访问了。

    有时候访问一个网页,如果输入域名不能访问,若知道 IP 地址直接输入后能访问,这就是域名服务器坏了或域名没有绑定。

  • URL

    URL(Uniform Resource Locator)统一资源定位符。这个大家应该不陌生,它就是我们使用 Web 浏览器访问网页时输入的网页地址。

    URL基本格式:例如:http://www.example.com:80/dir/index.html?id=1#hash2

    • http://:使用的协议... http 还 https,ftp,mailto 等(必选项)
    • www.example.com :HTTP 服务器的 IP 地址或域名地址(必选项)
    • 80 :端口号,HTTP 服务器的默认端口是 80,不输入时默认端口号,如果使用了其他端口号需指明,例如:http://www.example.com:8080
    • dir/index.html :带层次的文件路径,指定服务器上访问资源的路径
    • ?id=1 :发送给 http 服务器的查询数据(可选项)
    • #hash2 :锚点,hash 值,片段标识符(可选项)

三、HTTP 协议

我们知道,HTTP 协议用于客户端和服务器之间的通信。而使用 HTTP 协议进行通信时,又是通过请求和响应的交换来达成通信。请求必定由客户端发出,而服务器端回复响应。

HTTP 协议有下面几个特点:

  • 基于请求-响应的模式

    HTTP协议规定,请求从客户端发出,服务器端返回响应。即先从客户端开始建立通信的,服务器端在没有接收到请求之前不会发送响应。

  • 无状态性

    HTTP 协议不对之前发送过的请求或响应进行保存,即每次请求都是相互独立的。为了解决这个问题,于是引入 Cookie 的机制来保持状态。

  • 明文传输,不会对通信方进行确认
  • 默认端口是80

四、HTTP 请求和响应

HTTP 协议的消息类型共分为两大类:

  • 请求 Request:由客户端发送给服务器端的消息。
  • 响应 Response:服务端回应客户端请求的消息。

而用于 HTTP 协议交互的信息被称为 HTTP 报文。报文是 HTTP 通信中的基本单位,由客户端发出的 HTTP 报文叫请求报文,服务器端的则叫做响应报文。

  • http 请求报文

    http 协议的请求报文内容由以下数据组成:

    • 请求行:描述请求的基本信息,包括请求方法、请求URL、协议版本;

      • 请求方法有:GET、POST、PUT、DELETE、......,表示对资源的操作;
      • 请求URL:标记了请求方法要操作的资源;
      • 协议版本:表示报文使用的协议版本。
    • 请求首部字段:使用key-value的形式说明报文(可选)

      • 灵活,可以任意添加自定义头字段;
      • 字段名不区分大小写,字段名里不允许出现空格,可使用连字符 ‘-’;
      • 字段的顺序不影响语义;
      • 字段原则上不能重复,除非这个字段本身的语义允许,例如:Set-Cookie。
    • 内容主体:传输的数据,可以是文字、图片、视频等(可选)
  • http 响应报文
    http 响应报文组成如下:

    • 状态行:表明响应结果的状态,包含协议版本、状态码及状态描述

      • 状态码:一个三位数,表示处理的结果,比如:200 是成功,500 是服务器错误;
      • 状态描述:作为状态码的补充说明。
    • 响应首部字段:

      • 响应首部结束后,和主体信息有一个空行(即使没有主体信息,空行也不能少)
    • 内容主体:有些响应报文没有该主体

    例如:我们在浏览器中访问百度新闻下的国内新闻这一分类,所发送的 HTTP 请求报文中的内容如图:

    返回的响应报文如下:

    在 HTTP 协议进行通信的过程中,无论是请求还是响应都会使用首部字段,它能起到传递额外重要信息的作用,比如:提供报文主体大小、所使用的语言、认证信息等内容。

  • http 首部字段
    HTTP 首部字段根据实际用途分为以下四种类型:

    • 通用首部字段:

      即在请求报文和响应报文中都会使用的字段,如:

      • Cache-Control:控制缓存的行为,这个非常重要,用来指定请求和响应应遵循的缓存机制。具体各个指令的含义请查阅
      • Connection:控制不再转发给代理的首部字段、管理持久连接(Connection: keep-alive / close)。
      • Date:创建报文的日期时间。
    • 请求首部字段

      请求头中的字段,补充了请求的附加内容、客户端信息等,如:

      • Accept:告知服务端用户代理能够处理的内容类型(如 Accept: application/json, text/plain)。
      • Accept-Language:优先的语言(中文或英文等,Accept-Language: zh-CN,zh;q=0.8)。
      • Host:客户端指定要访问的请求资源所在服务器的域名或者IP地址和端口号(Host: news.baidu.com)。Host 是 HTTP/1.1 规范内是唯一一个必须被包含在请求内的首部字段。
      • Authorization:和首部字段 Proxy-Authorization 可起相同作用,即告知服务器认证所需要的信息。
      • User-Agent:客户端程序的信息,比如当前使用的浏览器的名称和版本信息等。
    • 响应首部字段

      响应头中的字段,补充了响应的附加内容,如:

      • Server:当前服务器上安装的 HTTP 服务器的信息,包括软件应用名称、版本号等,如:Server: nginx/1.18.0
    • 实体首部字段

      针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更新时间等与实体有关的信息。

    以上罗列了报文中的部分首部字段,更多字段查阅

五、持久连接

HTTP 协议是基于 TCP/IP 协议之上的。在 HTTP/1.1 之前的版本中,每进行一次 HTTP 通信就要断开一次 TCP 连接,这样效率是非常低的。当我们浏览一个含有多张图片的 web 页面时,每次的请求都会造成无谓的 TCP连接建立和断开,从而产生大量的通信开销。

所以在 HTTP/1.1 版本后,增加了持久连接。HTTP持久连接HTTP persistent connection,也称作 HTTP keep-aliveHTTP connection reuse)旨在使用同一个 TCP 连接来进行多个 HTTP 请求和响应的交互,而不是为每一个新的请求和响应创建新的连接。

即只要任意一端没有明确提出断开连接,则保持 TCP 连接状态。当客户端发送另一个请求时,它会使用同一个连接,这一直继续到客户端或服务器端认为会话已经结束。这样做的好处是减少了重复的 TCP 连接的建立和断开所造成的额外开销,减轻了服务器端的负载。

在 HTTP 首部字段中我们提到 Connection 字段可以管理持久连接。在 HTTP/1.1 中,所有的连接默认都是持久连接的,如果想断开连接时,则指定 Connection: Close;但 HTTP/1.1 之前的版本如果想维持持久连接,则需在请求首部字段中指定 Connection: Keep-Alive,然后当服务器收到请求,作出回应的时候,它也会添加在响应头中。

六、HTTP 状态码

借助状态码,我们可以知道服务器端的请求是正常处理了,还是出现了错误。

HTTP 状态码的职责是当客户端向服务器端发送请求时,描述返回的请求结果、标记服务器端的处理是否正常、及出现的错误等。以下列出了具有代表性的几种状态码:

注意:

  • 当从浏览器发出请求处理后返回 204 响应状态码,浏览器显示的页面不发生更新;
  • 当 301、302、303 响应状态码返回时,几乎所有的浏览器都会把 POST 改成 GET,并删除请求报文内的主体,之后请求会自动再次发送;
  • 301、302 标准是禁止将 POST 方法改变成 GET 方法的,但实际使用时都会这么做;
  • 303 状态码明确表示客户端应当采用 GET 方法获取资源;
  • 304 的附带条件的请求是指采用 GET 方法的请求报文中包含 If-Match、If-Modified-Since、IF-None-Match、IF-Range、If-Unmodified-Since 中的任一首部;
  • 307 会遵照浏览器标准,不会从 POST 变成 GET。

HTTP 标准状态码还是比较多的,以上只列出了常见状态码。在实际开发过程中,我们也可以自定义创建状态码,比如服务器出现问题,但响应结果依然会返回200的情况。

七、HTTP 请求的完整过程

以上,了解了 HTTP 通信相关的概念,下面这张图帮助我们概括了在 HTTP 协议的通信过程中,IP 协议、TCP 协议和 DNS 服务各自起到了哪些作用。

那么,当我们在浏览器中输入 www.baidu.com 然后回车,浏览器就显示了百度这个网页,在这个过程中到底发生了什么呢?具体的工作流程是怎样的呢?

  1. 首先干活的是浏览器应用程序,它要向 DNS 服务器请求解析该 URL 中的域名及对应的 IP 地址;
  2. 解析出 IP 地址后,浏览器就可以发起与服务器的三次握手;
  3. 建立 TCP 连接后,浏览器组装并发送 http 请求报文的数据给服务器;
  4. 服务器收到请求报文后,解析请求报文并对浏览器请求作出响应;
  5. 浏览器收到响应数据后,开始渲染页面;
  6. 浏览器与服务器断开链接。

八、HTTPS

由于 HTTP "天生明文"的特点,整个传输过程完全透明,任何人都能够在链路中截获、修改或者伪造请求/响应报文,数据不具有可信性。因此就诞生了为安全而生的 HTTPS 协议,全称 Hyper Text Transfer Protocol over Secure Socket Layer。使用 HTTPS 时,所有的 HTTP 请求和响应在发送到网络之前,都要进行加密。HTTPS 是以安全为目标的 HTTP 通道,简单讲是 HTTP 的安全版。

  • HTTP 和 HTTPS 的区别

    即使孪生也有不同之处:

    • HTTPS 协议需要到 CA 申请证书,一般免费证书很少,需要交费。
    • HTTP 是明文传输,HTTPS 则是具有安全性的 SSL 加密传输。
    • HTTP 和 HTTPS 使用的端口也不一样,前者是80,后者是443。
    • HTTPS 可进行加密传输、身份认证,比 HTTP 安全。
  • SSL/TLS

    SSL 即安全套接层(Secure Sockets Layer),由网景公司与1994年发明,IETF 在1999年把它改名为 TLS(传输层安全,Tfansport Layer Security)。TLS与SSL在传输层与应用层之间对网络连接进行加密,是为网络通信提供安全及数据完整性的一种安全协议。

  • 加密算法

    • 对称秘钥加密算法:编、解码使用相同秘钥的算法,如 AES, RC4, ChaCha20...
    • 非对称秘钥加密算法:它有两个秘钥,一个叫“公钥”,一个叫“私钥”。两个秘钥是不同的,公钥可以公开给任何人使用,而私钥必须严格保密。非对称加密可以解决“秘钥交换”的问题。网站秘密保管私钥,在网上任意分发公钥,你想要登录网站只要用公钥加密就行了,密文只能由私钥持有者才能解密。而黑客因为没有私钥,所有就不发破解密文。非对称秘钥加密系统通常需要大量的数学运算,速度比较慢,如 DH、DSA、RSA、ECC...
    • HTTPS 使用的是混合加密机制,即把对称加密和非对称加密结合起来,两者互相取长补短,既能高效的加密解密,又能安全的交换秘钥。

PS:以上内容主要基于 http/1.1 版本,也是我在理解 http 协议通信过程中的笔记吧,主要参考了《图解HTTP》这本书,文章中部分插图也来自于此书。
不足之处,欢迎指正,感谢 :)

附图书下载:

《图解HTTP》、《HTTP权威指南》 (提取码:vmfe)


sugar_coffee
455 声望19 粉丝