技术是为了解决特定问题而出现的。当我们学习一项技术时,一定要抓住问题。
背景
WWW 最初的设想的基本理念是:借助多文档之间相互关联形成的超文本,连接成可相互参阅的 WWW(World Wide Web 即万维网)
- WWW 构建技术
- 把HTML作为页面的文本标记语言
- 把http(超文本传输协议)作为文档传输协议
- 指定文档所在地址为URL(Uniform Resource Locator)
所以,HTTP协议起初是为了解决互联网中文本传输的问题。
网络基础 TCP/IP
- TCP/IP的分层管理
TCP/IP协议族按照层次,从上往下依次是:应用层,传输层,网络层,数据链路层- 应用层
应用层决定了向用户提供各种服务。比如:FTP(文件传输协议),HTTP(超文本传输协议),DNS(Domain Name System 域名解析系统)服务 - 传输层
传输层向应用层,提供处于网络连接中的计算机之间的数据传输。该层有两个协议:TCP(Transmission Control Protocol 传输控制协议)和UDP(User Data Protocol 用户数据报协议) - 网络层
网络层用来处理在网络上流动的数据包(网络传输的最小单位)。该层规定了通过怎样的路径到达对方计算机,并把数据包传送给对方。如:ARP(Address Resolution Protocol 根据IP地址解析出对应的MAC地址) - 数据链路层
用来处理网络连接的硬件部分,包括控制操作系统,设备驱动以及光纤等物理部分。
- 应用层
利用TCP/IP协议族进行网络通信时,发送端从应用层往下传递数据包,接收端从数据链路层网上接收数据包。
-
IP
IP在 TCP/IP协议族中处于网络层,它是一种协议的总称,它的作用就是把网络中传递的数据包传送给对方。
如何保证确实传送到对方那?需要满足两个条件。1. IP地址,指明节点要到达的地址。IP地址是可变的。2. MAC地址,指向网卡所属的固定地址。一台计算机只有一个MAC地址且不会变。
-
TCP
TCP属于传输层,为了更容易的传递大块数据,常常将数据分割成以报文段(segment)为单位的数据包。而且,TCP协议使用三次握手,能够确认数据最终是否送达对方。
-
URI(Uniform Resource Identifier)
统一资源标识符。由某个协议方案(http,ftp)表示的资源的定位标识符。例如:人可以用身份证来表示,也可以用工号来表示,身份证和工号就是URI。URI格式:以http协议为例。 http://user:pass@www.baidu.com:8080/main/index.html?uid=110#ch1。
URL
统一资源定位符。严格遵循URI的格式,用来表示资源具体位置。例如:要找到某一个人,只知道他的姓名不可以,只知道他的工号不可以,必须是身份证上的家庭地址。而这个家庭地址就是URL。可见,URL是URI的一个子集。
HTTP
HTTP协议符合基于请求/响应模型,用于客户端与服务端的通信,通过请求和响应(网络连接中的数据包)的交换达成通信。
HTTP协议是无状态的可靠协议。
- 无状态
自身不会之前发生过的请求和响应的状态进行管理,也就是说无法根据之前的状态进行本次的请求处理。由于不必保存状态,自然可以减少服务器的CPU以及内存消耗。但是另一方面,由于无状态,导致在特定的场景(登录,历史记录)下非常麻烦。
为了实现保留状态,HTTP引入了 Cookie技术:根据从服务端发送的响应报文内的一个 Set-Cookie 首部字段,通知客户端保存 Cookie。当下次客户端再向该服务器发送请求时,客户端会自动在请求报文中加入 Cookie值。
- 长连接/短连接
在请求一个包含多个图片的Web网页时,如果HTTP不支持长连接,那么每请求一张图片就新建/断开一个TCP连接,增加了通信的开销。
长连接是指在一次网络请求中,客户端与服务端都明确设置了 Keep-Alive,只要任意一端没有明确提出断开TCP连接,则保存TCP连接状态。在请求超过指定时间后,没有再次发起请求,那么服务端会主动断开TCP连接。
HTTP1.0默认不是长连接的,需要客户端与服务端同时设置 Keep-Alive;Http1.1默认是支持长连接的。
- 长轮询/短轮询
短轮询:客户端不断的向服务端发请求,服务端资源有没有更新,都会立即作出响应,将资源返回。这样的话,服务器的消耗比较大,客户端的消耗也挺大
长轮询:客户端不短的向服务器发请求,但服务器会把这个请求挂起一段时间,在这个时间内,服务端自己去查询资源有没有发生变化,有变化就返回,没变化就一直等到超时。
从上面可见,长轮询与短轮询,客户端的操作没有变化,变得是服务端的处理。另外,无论是长轮询还是短轮询都不适合请求量大的情况。
报文
报文是http协议在网络连接中进行通信的数据的最小单位,它是一种明文显示的字符串请求端发出的报文称为请求报文,服务端发出的报文称为响应报文。
请求
请求是由客户端发起的。当我们在浏览器输入一个URL,并按下 Enter键,就发起了一个请求。那么请求长什么样子那?
请求由请求行,请求头,空行,请求数据组成
- 请求行
GET /temp/index.html HTTP/1.1
- 请求头
- 空行
- 请求数据
响应
响应是服务器对客户端期望做出的回应。由 响应行,响应头,空行,响应正文组成
- 响应行
HTTP1.1 200 ok
- 响应头
- 空行
- 响应正文
状态码:
- 1XX: 请求正在处理中
- 2xx: 请求正常处理
- 3xx: 重定向,需要客户端进一步操作
- 4xx: 客户端错误,请求语法有问题
- 5xx: 服务端错误,服务端未能正常处理请求
头部
头部内容为客户端和服务器分别出来请求和响应提供了所需要的信息。
- 通用头部
请求报文和响应报文都会使用的头部字段。
---|---
字段名|说明
Cache-Control|控制缓存的行为,如:
Connection|管理连接的行为
- 请求头部
从客户端向服务器发送请求时使用的头部。
---|---
字段名|说明
Host|请求资源所在服务器,以字符串形式显示
If-Match|比较资源的Etag标记,匹配则返回全部资源
If-None-Match|比较资源的Etag比较,不匹配则返回全部资源
If-Modified-Since|比较资源的更新时间
If-Range|它执行了两步操作:1. 比较资源的Etag标记,如果不匹配(说明服务端资源已更新,客户端的缓存数据已失效),则返回全部资源;如果匹配,则返回 Range 指定的 bytes 范围内的数据。
Range|请求数据的字节范围
- 响应头部
从服务器向客户端发送响应时使用的头部
---|---
字段名|说明
Accept-Range|服务端是否能处理范围请求
Etag|服务器资源的唯一标记
Location|令客户端重定向到指定URL
- 实体头部
请求报文和响应报文的实体部分使用的头部
---|---
字段名|说明
Content-Type|实体的数据类型
Content-Range|范围请求时,想要的资源的块数据范围
Content-Length|数据返回的大小(单位:字节 byte)
Last-Modified|资源的最后修改时间
Content-Encoding|内容的编码方式
HTTP的缺点
1. 通信使用明文(不加密),容易被窃听。
由于TCP/IP协议族的工作机制,通信内容在整个通信线路中都可能遭到窃听。例如:抓包工具,Charless,Wireshark,那么如何加密防止窃听那?
- 通信加密
HTTP协议本身没有加密机制,但是得益与它的扩展性,可以通过与SSL或者TLS组合使用,对整个通信线路进行加密。
- 内容加密
将内容实体进行加密。即请求过程中使用双向加密算法,对请求体进行加密,相应的,服务器也要对请求进行解密。
2. 不验证通信方的身份,因此有可能。
Http协议中的请求和响应不会对通信方进行确认。因此,存在"服务器是否就是发送请求中URI指定的主机,响应是否真的返回到请求发起的客户端"等类似验证问题。
3. 无法证明报文的完整性,因此实体可能已遭篡改。
所谓完整性是指信息的准确度,如果无法证明其完整性,通常也就意味着无法判断信息是否准确
中间人攻击:请求和响应在传输途中,遭攻击者拦截并篡改内容的攻击称为中间人攻击
HTTPS
为了解决HTTP的缺点带来的问题,我们使用HTTPS进行通信。那么HTTPS是什么那?
HTTPS = HTTP + 加密 + 认证 + 完整性保护。换句话说,HTTPS是加了一层SSL协议的HTTP,所以,HTTPS并不是一个新协议。
HTTP在使用时,通常直接与TCP进行通信。但HTTPS在使用时,HTTP会先与SSL通信,再有SSL和TCP通信。
那么SSL是如何实现加密,认证与完整性保护的那?我们通过一次HTTPS通信来看一下。
1. 客户端发送请求报文,开始与SSL通信。报文中包含SSL的版本,加密组件列表
2. 如果服务器可以进行SSL通信,则会发送响应报文到客户端。报文中包含SSL版本以及加密组件。服务器的加密组件是从接收到客户端加密组件中筛选出来的。
3. 服务器发送包含**公钥**证书的报文到客户端
4. 服务端发送SSL握手结束的报文
5. SSL第一次握手结束后,客户端发送包含随机密码串的报文,该报文使用第3步骤中的**公钥**进行加密
6. 客户端继续发送报文,该报文的意义是:通知服务器,以后通信的报文都采用第5步的随机密码进行加密
7. 客户端发送 Finished 报文,表示这次SSL握手结束了。另外,这次SSL握手是否成功,要以服务器能否解密该报文作为判定标准。
8. 服务端发送报文,通知客户端,我能正确解密该报文
9. 服务端发送 Finished 报文,表示这次SSL握手结束了。
10. 客户端与服务端交换 Finishd报文后,SSL连接就算建立完成了。当然,通信过程是受保护的。
HTTP2.0
如何解决HTTP的性能瓶颈,缩短Web页面的加载时间?
-
HTTP的瓶颈
- HTTP1.0一条连接上只能发送一个请求,HTTP1.1默认支持长连接。
- 请求只能从客户端开始,客户端不可以接收除响应意外的指令
- 请求/响应首部没有经过压缩就发送。首部信息越多延迟越大,页面加载越慢
- 发送冗长的首部。每次通信都互相发送相同的首部,比较浪费资源
- 可任意选择数据压缩格式
-
HTTP2与HTTP的区别
- HTTP以明文形式在网络中通信,HTTP2以二进制形式在网络中通信
- HTTP把一次单向传输的内容称为包,HTTP2使用帧
- HTTP通过文本形式定义了起始行,报文头,和实体,HTTP2通过二进制格式定义了Length(整个二进制Frame的长度),Type(Frame的类型),Flags(用bit位定义重要的参数),Stream ID(HTTP把一次HTTP Request/Response 来回称为流,因为复用TCP连接,因此一个连接里可以有多个流,每个流都有唯一的ID),Payload(Request的正文)。HTTP2把HTTP1的起始行和报文头封装为 Headers Frame, 把实体封装为 Data Frame
- HTTP不指定内容编码方式,HTTP2统一使用二进制编码
-
HTTP2的特性
- 单连接多路复用
在同一个域名下,只使用一个TCP连接来加载一个页面的所有资源,在这个连接中可以打开多个流来同时传输数据。 - headers 压缩
为了减少报文头部的数据量,使用HPACK6算法对头部进行压缩。 - 服务端推送
由于HTTP中的流是双向的,所以服务器可以主动向客户端建立流。通过Server Push 和 Sercer Hint技术,主动的向客户端推送资源,同时不发送已经缓存的资源 - 优先级和依赖关系
每个流都有自己的优先级(0-7),服务器可以根据优先级优先处理流
- 单连接多路复用
总结:HTTP2 通过单连接多路复用来减少TCP连接与销毁的频率,减少延迟;通过 HPACK算法将头部压缩,减少因首部信息过大,引起的延迟;通过二进制数据,代替明文形式的文本数据,即增强了安全性,也减少了流量使用;增加请求优先级,可以优先处理重要的请求;丢弃由客户端发起请求,且客户端不能接收除响应外的指令,改用全双工模式。