一、碎碎念
1. 报文
报文分为请求报文和响应报文,格式如下:

二、GET和POST区别
网络上流传有两种版本,一种是表现上的区别,一种是RFC规范上也就是语义上的区别。
表现上的区别
GET后退按钮/刷新无害,POST数据会被重新提交(浏览器应该告知用户数据会被重新提交)。
GET书签可收藏,POST为书签不可收藏。
GET能被缓存,POST不能缓存。
GET编码类型application/x-www-form-url,POST编码类型encodedapplication/x-www-form-urlencoded 或multipart/form-data。为二进制数据使用多重编码。
GET历史参数保留在浏览器历史中。POST参数不会保存在浏览器历史中。
GET对数据长度有限制,当发送数据时,GET 方法向 URL 添加数据;URL 的长度是受限制的(URL 的最大长度是 2048 个字符)。POST无限制。
GET只允许 ASCII 字符。POST没有限制。也允许二进制数据。
与 POST 相比,GET 的安全性较差,因为所发送的数据是 URL 的一部分。在发送密码或其他敏感信息时绝不要使用 GET !POST 比 GET 更安全,因为参数不会被保存在浏览器历史或 web 服务器日志中。
GET的数据在 URL 中对所有人都是可见的。POST的数据不会显示在 URL 中。
语义上的区别
RFC7231里定义了HTTP方法的几个性质:
Safe -
安全这里的「安全」和通常理解的「安全」意义不同,如果一个方法的语义在本质上是「只读」的,那么这个方法就是安全的。客户端向服务端的资源发起的请求如果使用了是安全的方法,就不应该引起服务端任何的状态变化,因此也是无害的。 此RFC定义,GET, HEAD, OPTIONS 和 TRACE 这几个方法是安全的。但是这个定义只是规范,并不能保证方法的实现也是安全的,服务端的实现可能会不符合方法语义,正如上文说过的使用GET修改用户信息的情况。引入安全这个概念的目的是为了方便网络爬虫和缓存,以免调用或者缓存某些不安全方法时引起某些意外的后果。User Agent(浏览器)应该在执行安全和不安全方法时做出区分对待,并给用户以提示。
Idempotent -
幂等幂等的概念是指同一个请求方法执行多次和仅执行一次的效果完全相同。按照RFC规范,PUT,DELETE和安全方法都是幂等的。同样,这也仅仅是规范,服务端实现是否幂等是无法确保的。引入幂等主要是为了处理同一个请求重复发送的情况,比如在请求响应前失去连接,如果方法是幂等的,就可以放心地重发一次请求。这也是浏览器在后退/刷新时遇到POST会给用户提示的原因:POST语义不是幂等的,重复请求可能会带来意想不到的后果。
Cacheable -
可缓存性 顾名思义就是一个方法是否可以被缓存,此RFC里GET,HEAD和某些情况下的POST都是可缓存的,但是绝大多数的浏览器的实现里仅仅支持GET和HEAD。关于缓存的更多内容可以去看RFC7234。
三、TCP三次握手
1. 三次握手

2. 三次握手的意义
在客户端与服务器进行通信前,双方需确认自己和对方收发消息都没问题,这样才能保证在不可靠的网络上进行可靠的传输。客户端需要确认自己和服务器的收发功能都正常,服务器同样需要确认自己和客户端的收发功能都正常。
第一次握手: 客户端发送SYN到服务端,服务端接收到发送自客户端的SYN。此时客户端什么都确认不了,服务端可以确认客户端发送正常,自己接收正常。
第二次握手: 服务端发送SYN ACK到客户端,客户端接收到发送自服务器端的SYN ACK。此时客户端确认了自己发送接收都正常,服务端发送接收都正常。服务端确认了客户端发送正常,自己接收正常。
第三次握手: 客户端发送ACK到服务端,服务端接收到发送自客户端的ACK。此时客户端确认了自己发送接收都正常,服务端发送接收都正常。服务端确认了自己发送接收都正常,客户端发送接收都正常。
3. 为何不能是两次
假设只有前两次握手,没有第三次握手。一个客户端要与服务端通信,发送了一个SYN,由于网络原因,该请求报文在某个节点被长时间阻塞。一段时间后这个早已失效的报文被发送到服务端,服务端以为客户端要与之进行通信,于是发送了SYN ACK,并且等待客户端发来的数据,可是此时客户端早已变心,服务端只能白白浪费服务器资源。
四、TCP四次挥手
四次挥手不像三次握手命中几率那么大,盗张图得了。

由于TCP连接时全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭,上图描述的即是如此。
第一次挥手:
Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
第二次挥手:
Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
第三次挥手:
Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
第四次挥手:
Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。
五、对称加密,非对称加密
对称加密指的就是加密和解密使用同一个秘钥,所以叫做对称加密。对称加密只有一个秘钥,作为私钥。
常见的对称加密算法:DES,AES,3EDS等等。
非对称加密指的是:加密和解密使用不同的秘钥,一把作为公开的公钥,另一把作为私钥。公钥加密的信息,只有私钥才能解密。私钥加密的信息,只有公钥才能解密。
常见的非对称加密算法:RSA,ECC
六、HTTPS介绍,握手流程
继续盗图

-
客户端发出一个 client hello 消息,携带的信息包括:
所支持的SSL/TLS 版本列表;支持的与加密算法;所支持的数据压缩方法;随机数A;
-
服务端响应一个 server hello 消息,携带的信息包括:
协商采用的SSL/TLS 版本号;会话ID;随机数B;服务端数字证书 serverCA;
由于双向认证需求,服务端需要对客户端进行认证,会同时发送一个 client certificate request,表示请求客户端的证书;
-
客户端校验服务端的数字证书;校验通过之后发送随机数C,该随机数称为pre-master-key,使用数字证书中的公钥加密后发出;
由于服务端发起了 client certificate request,客户端使用私钥加密一个随机数 clientRandom随客户端的证书 clientCA一并发出;
-
服务端校验客户端的证书,并成功将客户端加密的随机数clientRandom 解密;
根据 随机数A/随机数B/随机数C(pre-master-key) 产生动态密钥 master-key,加密一个finish 消息发至客户端;
-
客户端根据 同样的随机数和算法 生成master-key,加密一个finish 消息发送至服务端;
-
服务端和客户端分别解密成功,至此握手完成,之后的数据包均采用master-key进行加密传输。
七、在浏览器输入网址发生了什么?
- DNS解析(通过访问的域名找出其IP地址,递归搜索)
- HTTP请求,当输入一个请求时,建立一个Socket连接发起TCP的3次握手
- 如果是HTTPS请求建立连接后,则看Q26
- 客户端向服务器发送请求命令(一般是GET或POST请求)
- 客户端发送请求头信息
- 服务器发送应答头信息
- 服务器向客户端发送数据
- 服务器关闭TCP连接(4次挥手)
- 客户端根据返回的HTML,CSS,JS进行渲染
八、前瞻
SPDY:
是Google开发的基于TCP的应用层协议,用以最小化网络延迟,提升网络速度,优化用户的网络使用体验。SPDY并不是一种用于替代HTTP的协议,而是对HTTP协议的增强。新协议的功能包括数据流的多路复用、请求优先级以及HTTP报头压缩。
TFO:
-
客户端发送一个SYN包到服务器,这个包中携带了Fast Open Cookie Request;
-
服务器生成一个cookie,这个cookie是加密客户端的IP地址生成的。服务器给客户端发送SYN+ACK响应,在响应包的选项中包含了这个cookie;
-
客户端存储这个cookie以便将来再次与这个服务器的IP建立TFO连接时使用;
也就是说,第一次TCP连接只是交换cookie信息,无法在SYN包中携带数据。在第一次交换之后,接下来的TCP连接就可以在SYN中携带数据了。流程如下:
-
客户端发送一个SYN包,这个包比较特殊,因为它携带应用数据和cookie;
-
服务器验证这个cookie,如果合法,服务器发送一个SYN+ACK,这个ACK同时确认SYN和数据。然后数据被传递到应用进程;
如果不合法,服务器丢弃数据,发送一个SYN+ACK,这个ACK只确认SYN,接下来走三次握手的普通流程;
-
如果验证合法(接收了SYN包中的数据),服务器在接收到客户端的第一个ACK前可以发送其它响应数据;
-
如果验证不合法(客户端在SYN中带的数据没被确认),客户端发送ACK确认服务器的SYN;并且,数据会在ACK包中重传;
-
下面的流程与普通的TCP交互流程无异。
HTTP2与HTTP1.1区别
