这是对图解HTTP这本书的总结,有兴趣的可以把这本书看下,里面的配图我很喜欢
TCP/IP协议族按层次分别分为以下4层:应用层、传输层、网络层和数据链路层。
① 应用层
应用层决定了向用户提供应用服务时通信的活动。TCP/IP协议族内预存了各类通用的应用服务。比如,FTP(File TransferProtocol,文件传输协议)和DNS 服务就是其中两类。HTTP协议也处于该层。
② 传输层
对上层应用层,提供处于网络连接中的两台计算机之间的数据传输。在传输层有两个性质不同的协议:TCP(Transmission Control Protocol,传输控制协议)和UDP(User Data Protocol,用户数据报协议)。
③ 网络层(又名网络互连层)
网络层用来处理在网络上流动的数据包。数据包是网络传输的最小数据单位。该层规定了通过怎样的路径(所谓的传输路线)到达对方计算机,并把数据包传送给对方。与对方计算机之间通过多台计算机或网络设备进行传输时,网络层所起的作用就是在众多的选项内选择一条传输路线。
④ 链路层(又名数据链路层,网络接口层)
用来处理连接网络的硬件部分。包括控制操作系统、硬件的设备驱动、NIC(Network Interface Card,网络适配器,即网卡),及光纤等物理可见部分(还包括连接器等一切传输媒介)。硬件上的范畴均在链路层的作用范围之内。
利用TCP/IP协议族进行网络通信时,会通过分层顺序与对方进行通信。发送端从应用层往下走,接收端则往应用层往上走。发送端在层与层之间传输数据时,每经过一层时必定会被打上一个该层所属的首部信息。反之,接收端在层与层传输数据时,每经过一层时会把对应的首部消去。
WebSocket和HTTP协议的关系:服务器都是处于被动状态,只能接受客户端的请求,这样客户端只有通过经常发送请求来确认是否有数据更新,但是大多数时候都是没有数据更新的,这样会造成很大的浪费,所以就产生了webSocket协议,这个协议就是为了改变服务器的被动状态,使用这个协议后,服务端可以主动给客户端发送信息。
HTTP协议规定,请求从客户端发出,最后服务器端响应该请求并返回。换句话说,肯定是先从客户端开始建立通信的,服务器端在没有接收到请求之前不会发送响应。
① 请求报文
请求报文包含四部分:
起始行开头的POST表示请求访问服务器的类型,称为方法(method)。随后的字符串URI指明了请求访问的资源对象, 最后的HTTP/1.1,即HTTP的版本号,用来提示客户端使用的HTTP协议功能。
② 响应报文
响应报文包含四部分:
接收到请求的服务器,会将请求内容的处理结果以响应的形式返回。第一行也叫状态行,请求报文的第一行叫请求行。
常见的首部:
URI,是uniform resource identifier,统一资源标识符,用来唯一的标识一个资源。
Web上可用的每种资源如HTML文档、图像、视频片段、程序等都是一个来URI来定位的
URL是uniform resource locator,统一资源定位器,它是一种具体的URI,即URL可以用来标识一个资源,而且还指明了如何locate这个资源。
URL是Internet上用来描述信息资源的字符串,主要用在各种WWW客户程序和服务器程序上,特别是著名的Mosaic。采用URL可以用一种统一的格式来描述各种信息资源,包括文件、服务器的地址和目录等。URL一般由三部组成:
① GET:获取资源
GET方法用来请求访问已被URI识别的资源。指定的资源经服务器端解析后返回响应内容。也就是说,如果请求的资源是文本,那就保持原样返回;如果是程序,则返回经过执行后的输出结果。
② POST:传输实体主体
POST方法用来传输实体的主体。虽然用GET方法也可以传输实体的主体,但一般不用GET方法进行传输,而是用POST方法。虽说POST的功能与GET很相似,但POST的主要目的并不是获取响应的主体内容。
③ PUT:传输文件
PUT方法用来传输文件。就像FTP协议的文件上传一样,要求在请求报文的主体中包含文件内容,然后保存到请求URI指定的位置。但是,鉴于HTTP/1.1的PUT方法自身不带验证机制,任何人都可以上传文件,存在安全性问题,因此一般的Web网站不使用该方法。若配合Web应用程序的验证机制,或架构设计采用REST 标准的同类Web网站,就可能会开放使用PUT方法。
④ DELETE:删除文件
DELETE方法用来删除文件,是与PUT相反的方法。DELETE方法按请求URI删除指定的资源。
GET和POST是HTTP请求的两种基本方法,最直观的区别就是GET把参数包含在URL中,POST通过request body传递参数。
本质上没有太大的区别,最大的区别在于:GET产生一个TCP数据包,POST产生两个TCP数据包
对于GET方式的请求,游览器会把http header和data一并发送出去,服务器响应200(返回数据);而对于POST请求。游览器先发送header,服务器响应100 continue,游览器再发送data,服务器响应200 ok(返回数据)
也就是说,GET只需要汽车跑一趟就把货送到了,而POST得跑两趟,第一趟,先去和服务器打个招呼“嗨,我等下要送一批货来,你们打开门迎接我”,然后再回头把货送过去。
因为POST需要两步,时间上消耗的要多一点,看起来GET比POST更有效。因此Yahoo团队有推荐用GET替换POST来优化网站性能。但这是一个坑!跳入需谨慎。为什么?
GET与POST都有自己的语义,不能随便混用。
据研究,在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。
并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。
HTTP协议的初始版本中,每进行一次HTTP通信就要断开一次TCP连接。
以当年的通信情况来说,因为都是些容量很小的文本传输,所以即使这样也没有多大问题。可随着HTTP的普及,文档中包含大量图片的情况多了起来。比如,使用浏览器浏览一个包含多张图片的HTML页面时,在发送请求访问HTML页面资源的同时,也会请求该HTML页面里包含的其他资源。因此,每次的请求都会造成无谓的TCP连接建立和断开,增加通信量的开销。
为解决上述TCP连接的问题,HTTP/1.1和一部分的HTTP/1.0想出了持久连接的方法。持久连接的特点是,只要任意一端没有明确提出断开连接,则保持TCP连接状态。
持久连接的好处在于减少了TCP连接的重复建立和断开所造成的额外开销,减轻了服务器端的负载。另外,减少开销的那部分时间,使HTTP请求和响应能够更早地结束,这样Web页面的显示速度也就相应提高了。
持久连接使得多数请求以管线化(pipelining)方式发送成为可能。从前发送请求后需等待并收到响应,才能发送下一个请求。管线化技术出现后,不用等待响应亦可直接发送下一个请求。
样就能够做到同时并行发送多个请求,而不需要一个接一个地等待响应了。
比如,当请求一个包含10张图片的HTML Web页面,与挨个连接相比,用持久连接可以让请求更快结束。而管线化技术则比持久连接还要快。请求数越多,时间差就越明显。
状态码的职责是当客户端向服务器端发送请求时,描述返回的请求结果。借助状态码,用户可以知道服务器端是正常处理了请求,还是出现了错误。
常见的HTTP相应状态码
① 通信使用明文(不加密),内容可能会被窃听
HTTP报文使用明文(指未经过加密的报文)方式发送。按TCP/IP协议族的工作机制,通信内容在所有的通信线路上都有可能遭到窥视。
② 不验证通信方的身份,因此有可能遭遇伪装
HTTP协议中的请求和响应不会对通信方进行确认。也就是说存在 服务器是否就是发送请求中URI真正指定的主机,返回的响应是否真的返回到实际提出请求的客户端 等类似问题。
③ 无法证明报文的完整性,所以有可能已遭篡改
由于HTTP协议无法证明通信的报文完整性,因此,在请求或响应送出之后直到对方接收之前的这段时间内,即使请求或响应的内容遭到篡改,也没有办法获悉。
① 如果在HTTP协议通信过程中使用未经加密的明文,比如在Web页面中输入信用卡号,如果这条通信线路遭到窃听,那么信用卡号就暴露了。
② 对于HTTP来说,服务器也好,客户端也好,都是没有办法确认通信方的。因为很有可能并不是和原本预想的通信方在实际通信。
③ 并且还需要考虑到接收到的报文在通信途中已经遭到篡改这一可能性。
为了统一解决上述这些问题,需要在HTTP上再加入加密处理和认证等机制。我们把添加了加密及认证机制的HTTP称为HTTPS
HTTPS并非是应用层的一种新协议。只是HTTP通信接口部分用SSL 和TLS 协议代替而已。在采用SSL后,HTTP就拥有了HTTPS的加密、证书和完整性保护这些功能。
加密和解密都会用到密钥。没有密钥就无法对密码解密,反过来说,任何人只要持有密钥就能解密了。如果密钥被攻击者获得,那加密也就失去了意义。
加密和解密同用一个密钥的方式称为对称密钥加密,也叫共享秘钥加密。
**以共享密钥方式加密时必须将密钥也发给对方。可究竟怎样才能安全地转交?**在互联网上转发密钥时,如果通信被监听那么密钥就可会落入攻击者之手,同时也就失去了加密的意义。另外还得设法安全地保管接收到的密钥。
公开密钥加密使用一对非对称的密钥。一把叫做私有密钥 ,另一把叫做公开密钥 。顾名思义,私有密钥不能让其他任何人知道,而公开密钥则可以随意发布,任何人都可以获得。
使用公开密钥加密方式,发送密文的一方使用对方的公开密钥进行加密处理,对方收到被加密的信息后,再使**用自己的私有密钥进行解密。**利用这种方式,不需要发送用来解密的私有密钥,也不必担心密钥被攻击者窃听而盗走。
HTTPS采用共享密钥加密和公开密钥加密两者并用的混合加密机制。若密钥能够实现安全交换,那么有可能会考虑仅使用公开密钥加密来通信。但是公开密钥加密与共享密钥加密相比,其处理速度要慢。所以应充分利用两者各自的优势,将多种方法组合起来用于通信。在交换密钥环节使用公开密钥加密方式,之后的建立通信交换报文阶段则使用共享密钥加密方式。
在交换密钥环节,使用公开密钥加密技术( 从客户端到服务器,那么在这样一个安全的通信中,客户端使用服务器的公开秘钥对共享秘钥进行加密后,发送给服务器,然后服务器使用自己的私有秘钥进行解密,这样客户端就安全的将共享秘钥传给了服务器),之后建立通信报文交换的阶段则可使用共享密钥加密技术。
① Client发起一个HTTPS(比如https://juejin.im/user/5a9a9cdcf265da238b7d771c
)的请求,根据RFC2818的规定,Client知道需要连接Server的443(默认)端口。
② Server把事先配置好的公钥证书返回给客户端。
③ Client验证公钥证书:比如是否在有效期内,证书的用途是不是匹配Client请求的站点,是不是在CRL吊销列表里面,它的上一级证书是否有效,这是一个递归的过程,直到验证到根证书 。如果验证通过则继续,不通过则显示警告信息。
④ Client使用伪随机数生成器生成加密所使用的对称密钥,然后用证书的公钥加密这个对称密钥,发给Server。
⑤ Server使用自己的私钥 解密这个消息,得到对称密钥。至此,Client和Server双方都持有了相同的对称密钥。
⑥ Server使用对称密钥加密“明文内容A”,发送给Client。
⑦ Client使用对称密钥解密响应的密文,得到“明文内容A”。
⑧ Client再次发起HTTPS的请求,使用对称密钥加密请求的“明文内容B”,然后Server使用对称密钥解密密文,得到“明文内容B”。
HTTP 是明文传输协议,HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,比 HTTP 协议安全。
HTTPS需要用到SSL证书,而HTTP不用;
HTTPS标准端口443,HTTP标准端口80;
HTTPS基于传输层,HTTP基于应用层,HTTPS运行在SSL/TLS之上,SSL/TLS运行在TCP之上