什么是HTTP协议
超文本传输协议,是互联网上应用最为广泛的一种网络协议,用于规范客户端和服务端通信.
HTTP历史发展
1. HTTP/0.9
HTTP 的最早版本.没有 HTTP 头,没有状态码,甚至版本号也没有,只支持一种方法—— Get,只能传输文本.
2. HTTP/1.0
- 除了文字,还可以发送图片、视频等
- 请求与响应支持 HTTP 头,增加了状态码,响应对象的一开始是一个响应状态行
- 协议版本信息需要随着请求一起发送,支持 HEAD,POST 方法
3. HTTP/1.1
- 可以复用连接
- 增加 pipeline
- chunked 编码传输
- 引入更多缓存控制机制
- 引入内容协商机制
- 请求消息和响应消息都支持 Host 头域
- 新增了 OPTIONS,PUT, DELETE, TRACE, CONNECT 方法
4. HTTPS
超文本传输安全协议,关于https详解及与http区别下文会讲到.
5. SPDY
在 2010 年到 2015 年,谷歌通过实践一个实验性的 SPDY 协议,是http2的前身
- 页面加载时间 (PLT) 减少 50%。
- 无需网站作者修改任何内容。
- 将部署复杂性降至最低,无需变更网络基础设施。
- 与开源社区合作开发这个新协议。
- 收集真实性能数据,验证这个实验性协议是否有效。
6. HTTP/2.0
- 使用二进制分帧层
- 多路复用
- 数据流优先级
- 服务端推送
- 头部压缩
- 现实中的 HTTP2 都是在 HTTPS 上实现的
HTTP原理详解
HTTP协议是构建在TCP/IP协议族之上的,是TCP/IP协议族的一个子集,所以要理解HTTP协议,有必要先了解下TCP/IP协议族相关的知识。
TCP/IP协议族
TCP/IP协议族是由一个四层协议组成的系统,这四层分别为:应用层、传输层、网络层和数据链路层.
分层的好处是把各个相对独立的功能解耦,层与层之间通过规定好的接口来通信。如果以后需要修改或者重写某一个层的实现,只要接口保持不变也不会影响到其他层的功能。
- 应用层
应用层一般是我们编写的应用程序,其决定了向用户提供的应用服务。应用层可以通过系统调用与传输层进行通信。
处于应用层的协议非常多,比如:FTP(File Transfer Protocol,文件传输协议)、DNS(Domain Name System,域名系统)和我们本章讨论的HTTP(HyperText Transfer Protocol,超文本传输协议)等
- 传输层
传输层通过系统调用向应用层提供处于网络连接中的两台计算机(客户端和服务端)之间的数据传输功能。
在传输层有两个性质不同的协议:TCP(Transmission Control Protocol,传输控制协议)和UDP(User Data Protocol,用户数据协议)。
- 网络层
用来处理在网络上流动的数据包,数据包是网络传输的最小数据单位。该层规定了通过怎样的路径(传输路线)到达对方计算机,并把数据包传输给对方。
网络层中应用IP协议,此协议并不是DNS解析域名为ip地址的过程(DNS属于应用层),而是通过ip地址和MAC地址实现数据传输的协议.
- 链路层
链路层用来处理连接网络的硬件部分,包括控制操作系统、硬件设备驱动、NIC(Network Interface Card,网络适配器)以及光纤等物理可见部分。硬件上的范畴均在链路层的作用范围之内。
一次完整的HTTP事务流程
从浏览器输入地址到呈现内容,中间都经历了什么?
- 域名解析

解析过程:
- 浏览器DNS缓存
- 系统DNS缓存
- hosts文件
- 路由缓存
- 本地区域名服务器(LDNS)
- 根域名服务器
- 顶级域名服务器(com,net等)
- 发起TCP的三次握手

- 第一次握手:客户端发送带有SYN标志的连接请求报文段,然后进入SYN_SEND状态,等待服务端的确认。
- 第二次握手:服务端接收到客户端的SYN报文段后,需要发送ACK信息对这个SYN报文段进行确认。同时,还要发送自己的SYN请求信息。服务端会将上述的信息放到一个报文段(SYN+ACK报文段)中,一并发送给客户端,此时服务端将会进入SYN_RECV状态。
- 由服务器发起,告诉浏览器我准备接受了,你赶紧发送吧
- 第三次握手:客户端接收到服务端的SYN+ACK报文段后,会向服务端发送ACK确认报文段,这个报文段发送完毕后,客户端和服务端都进入ESTABLISHED状态,完成TCP三次握手。
- 由浏览器发送,告诉服务器,我马上就发了,准备接受吧
为啥三次握手:为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误
建立TCP连接后发起http请求
数据包封装

发送端发送数据时,数据会从上层传输到下层,且每经过一层都会被打上该层的头部信息。而接收端接收数据时,数据会从下层传输到上层,传输前会把下层的头部信息删除.
服务器响应http请求,浏览器得到HTML代码
浏览器解析HTML代码,并请求HTML代码中的资源
浏览器对页面进行渲染呈现给用户
连接结束TCP四次挥手

- 第一次: 客户端告诉服务端没有数据要发送了;我请求报文发送完了,你准备关闭吧
- 第二次: 服务端告诉客户端,知道了,我请求报文接受完了,但我还不确定有没有数据发给你,稍等
- 第三次: 服务端告诉客户端,我也没数据发送了,我响应报文发送完了,可以断开了
- 第四次: 客户端,收到了,我响应报文接受完了,断开吧
HTTP请求的消息结构
整个http消息结构分为request以及response两部分.详细参数解析

HTTPS
超文本传输安全协议,是安全通信通道,简单来说是 HTTP 的安全版本,是使用 TLS/SSL 加密的 HTTP 协议。

与http相比:

SSL/TLS
SSL/TLS 全称安全传输协议 Transport Layer Security,是介于 TCP 和 HTTP 之间的一层安全协议,不影响原来的 HTTP 和 TCP 协议。
SSL/TLS 的功能实现主要依赖于三类基本算法:散列函数、Hash、对称加密和非对称加密,其利用非对称加密实实现身份认证和密钥协商,对称加密算法采用协商的密码对数据加密,基于散列函数验证信息的完整性。

HTTP和HTTPS的区别
- HTTPS 是加密传输协议,HTTP 是明文传输协议
- HTTPS 需要用到 SSL/TLS 证书,而 HTTP 不用
- HTTPS 比 HTTP 更安全,对搜索引擎更友好,利于 SEO
- HTTS 标准端口443,HTTP 标准端口80
- HTTPS 基于传输层,HTTP 基于应用层
- HTTPS 在浏览器显示绿色安全锁,HTTP 没有
延伸问题
- 现代浏览器在与服务器建立了一个 TCP 连接后是否会在一个 HTTP 请求完成后断开?什么情况下会断开?
- 在http1.0中在服务器发完一个http响应后会断开tcp
- 由于这样代价非常大,即便标准中没有设定,但有些浏览器对Connection:keep alive进行支持.因此不会断开tcp链接.
- HTTP/1.1 就把 Connection 头写进标准,并且默认开启持久连接,除非请求中写明 Connection: close
- 一个 TCP 连接可以对应几个 HTTP 请求?
- 上述说了,tcp不会中断,因此能承载多个http请求
- 为什么有的时候刷新页面不需要重新建立 SSL 连接?
- TCP 连接有的时候会被浏览器和服务端维持一段时间。TCP 不需要重新建立,SSL 自然也会用之前的。
- 一个 TCP 连接中 HTTP 请求发送可以一起发送么(比如一起发三个请求,再三个响应一起接收)?
- http1.1中,一个tcp链接同一时刻只能处理一个http请求.为解决此问题,其中规范规定了Pipelining 来试图解决这个问题,但是这个功能在浏览器中默认是关闭的。
- Pipelining: 一个支持持久连接的客户端可以在一个连接中发送多个请求(不需要等待任意请求的响应)。收到请求的服务器必须按照请求收到的顺序发送响应。(同时响应的话,无法对应是哪个请求)
- Pipelining的问题: 一些代理服务器不能正确的处理 HTTP Pipelining;正确的流水线实现是复杂的; 连接阻塞(由于按顺序返回,即使其他请求处理完成,前边的请求超时,也要等待)
- HTTP2 提供了 Multiplexing 多路传输特性(并行请求,并行响应)
- 浏览器对同一 Host 建立 TCP 连接的数量有没有限制?
- Chrome 最多允许对同一个 Host 建立六个 TCP 连接。不同的浏览器有一些区别。
- 收到的 HTML 如果包含几十个图片标签,这些图片是以什么方式、什么顺序、建立了多少连接、使用什么协议被下载下来的呢?
- 如果图片都是 HTTPS 连接并且在同一个域名下,那么浏览器在 SSL 握手之后会和服务器商量能不能用 HTTP2,如果能的话就使用 Multiplexing 功能在这个连接上进行多路传输。
- 也可能建立多个 TCP 连接去获取,但可以确定的是 Multiplexing 很可能会被用到。
参考:
http系列
前端必知必会HTTP请求系列(一)了解Web及网络基础
前端必知必会HTTP请求系列(二)简单一点的HTTP协议
前端必知必会HTTP请求系列(三)HTTP报文内的http信息
HTTP和HTTPS协议,看一篇就够了
前端应该知道的http
写给前端的Http详解
Web前端面试——HTTP部分
深入理解HTTPS