计算机网络 - HTTP/WEB

目录

HTTP概念

非持续连接和持续连接 

 HTTP常见状态码

HTTP请求

Web缓存器 - 代理服务器

        条件GET方法

HTTP/1.1

        优点

        1. 简单

        2. 可拓展性

        3. 管道传输

        缺点

        1. 明文传输

        2. 不验证服务端身份

        3. 不验证报文的正确性

HTTP/1.1优化

HTTPS

       HTTP与HTTPS区别

        HTTPS的安全保障

        SSL/TLS建立过程

        为什么抓包程序能明文看到HTTPS的数据

HTTP/2

HTTP/3 

        1.解决队头阻塞

         2. 连接建立更快

        3. 连接迁移


HTTP概念

        HTTP全名为 HyperText Transfer Protocol,翻译为超文本传输协议

        1. HyperText 超文本表示HTTP传输的内容是超文本,它是文字、图像、视频等的混合体,关键的一点是它具有超链接功能,能够从一个超文本跳转到另一个超文本

        HTML是最基本的超文本,它自身是纯字符文件,但是用HTML的格式来规定了文字、图片、视频等内容,通过浏览器解读后为用户呈现一个漂亮的界面

        2. Transfer 传输表示点对点之间的传输

        3. Protocol 协议表示一种规范,由许多端来共同执行这个规范

        通过这三点可以归纳HTTP是在两点之间传输超文本数据的一种约定和规范

        这里有一点可以说说:传输虽然是点对点的传输,但是中间可以经过很多中介,但是最终是两点在进行传输,中间只是辅助

非持续连接和持续连接 

        HTTP点对点的交互是通过TCP进行的,在进行交互前需要先建立TCP连接,因此需要做一个重要的决定,当在服务器和客户端之间会有一系列的请求和响应时,每个请求和响应是经过一个单独的TCP连接来发送,还是所有的这些请求响应都经由同一个TCP连接来发送呢?

        这就是非持续连接和持续连接的区别

        HTTP对这两种连接都支持,但是一般默认使用持续连接

       非持续连接的HTTP

        除了第一次请求服务器的HTML文件需要建立TCP连接外,之后每次需要请求从这个HTML文件中解析出的各种文件还需要再次建立新的TCP连接,我们知道TCP连接采用三次握手的方式,是需要时间的,那每请求一个文件,就每多建立一个TCP连接,就每多消耗建立时间,在多个文件的请求中这是很浪费时间的!

        持续连接的HTTP

        除了第一次请求服务器的HTML文件需要建立TCP连接外,其他的请求过程都使用这一条TCP连接来进行请求和响应,不需要额外的建立TCP时间

        这样可以实现流水线响应

 HTTP常见状态码

        1XX:表示协议正在处理,请稍等

        2XX:表示成功状态,服务器成功处理了客户的请求

        3XX:表示请求的资源位置右边,需要客户端重新请求

                - 301 Moved Permanently:永久重定向,要用新的URL再次访问

                - 302 Moved Permanently:临时重定向,请求的资源还在,但是暂时需要用另外的URL

                - 304 Not Modified:资源还在,但是有缓存,可以获取

        4XX:表示客户端发送报文有问题,错误码

                - 400 Bad Request:笼统的表示报文有误

                - 403 Forbidden:禁止访问资源,该请求的资源不允许被客户端访问

                - 404 Not Found:请求的资源不存在

        5XX:服务器处理时内部出错,错误码

HTTP请求

        HTTP请求有很多,这里写出最常见的两种

        GET:向服务器请求数据

        GET方法是安全和幂等的,服务器上的数据是安全的,且每次结果都是相同的

        POST:向服务器提交数据

        POST方法是不安全也不幂等的

        但是往往对于安全的定义,不只是要保护服务器的数据,还要保护数据本身不被客户端和服务器之外的角色所获取,而这两个方法基于HTTP,都是明文传输,所以实际上并不能说是很安全!

        因此HTTPS协议就保护了这些明文数据,加密传输!

        注意!GET和POST只是RFC规定的建议使用规范,在实际设计过程中可以由开发者自行编写其代表的内容,也就是说GET可以是提交数据或删除数据,POST也可以是请求数据!

        这里有必要提一下条件GET方法,采用这个方法在后面代理服务器中会详细说到

        HTTP是一种无状态协议,HTTP服务器并不保存关于客户的任何信息,这就导致了如果某个特定的客户在短短几秒钟里多次请求资源,服务器并不会因为刚刚为这个客户提供了相关服务而做出特别的行动

        一个例子就是在淘宝购物时需要登录信息,我们现实生活中的情况是只需要登录一次即可,但是在无状态协议的情况下,每次操作(请求)都要知道客户的身份,从而每次操作都要进行登录,岂不是乱套了的购物体验?

        因此,HTTP采用了Cookie技术,简单地说就是通过在请求和响应报文中写入Cookie信息,来控制客户端信息

        在客户端的第一次请求后,服务器先检查现有的Cookie数据库中有无这个客户的记录,如果有则从中获取该客户的信息,并根据这个信息来给客户提供个性化的服务;如果没有,则在后端数据库中建立相关数据条,并在返回的响应报文中附带了一个Cookie,告诉客户端你的Cookie是这个,在之后的请求中,客户端就带上这个Cookie,服务器也就能知道这个客户的信息了

Web缓存器 - 代理服务器

        当客户端重复请求同一个服务器的同一个数据时,服务器如果每次都对这重复的请求进行响应,将会浪费很多时间,尤其是服务器距离客户端很远时,这种请求将是相当浪费时间的!

        因此Web缓存器应运而生,Web缓存器自带存储空间,当客户端向服务器请求数据时,先向这个Web缓存器发出请求,如果缓存器中存有这个请求的内容时,则直接从缓存器中提取,这样就避免了多次请求远程服务器的浪费!

        另外,代理服务器还可以用来进行URL的重定向,并在一次重定向服务后将重定向信息存储在代理服务器本地,这样需要重定向时,客户端可以经历更少的HTTP请求

        条件GET方法

        尽管这个代理服务器的想法很棒,但是还是会有一个问题:缓存器中的数据版本与服务器中的数据版本不一致!

        为此,条件GET方法就有必要存在了。当客户端请求一个数据时,代理服务器中找到了缓存,此时并不确定这个缓存的版本是否为最新,因此代理服务器会向真正的服务器发出条件GET请求,将本地的缓存的最后修改时间(Last-Modified)发送给服务器,服务器收到后与服务端的文件的最后修改时间比对,如果相同,则告知代理服务器可以直接使用这份缓存,否则服务器会将最新的文件发送给代理服务器,再由代理服务器转发给客户端

        在实际的HTTP处理中,缓存也会存在于本地,也就是说,浏览器本地也能存储缓存,这其中HTTP可以使用有两种情况,一种叫强制缓存,一种是协商缓存

        1. 强制缓存

                强制缓存指的是只要浏览器判断缓存没有过期,则直接使用浏览器的本地缓存,决定是否使用缓存的主动性在于浏览器这边。

                强制缓存同样需要通过一个缓存有效期来判断,在HTTP响应头部中有字段可以表示,这里又有两种选择 - Cache-Control(相对时间) 和 Expires(绝对时间)。

                一般推荐采用Cache-Control来实现,它的选项和设置更加精细

                · 当浏览器第一次请求访问服务器资源时,服务器会在返回这个资源的同时,在响应头部加上 Cache-Control,Cache-Control 中设置了过期时间大小

                · 当浏览器再次访问该资源时,会先比较请求该资源的时间和Cache-Control中设置的过期时间,如果没过期,则直接使用本地缓存,反之请求服务器

                · 如果再次访问服务器的这个资源,又会更新Cache-Control

        2. 协商缓存

                协商缓存意思是告诉浏览器可以使用本地缓存的资源,但是不强制直接使用。

                这通常通过上面提到的条件GET来实现

                · 浏览器发现本地的资源过期了,于是向服务器请求该资源时,会先询问服务器If-Modified-Since字段,该字段意为这个资源在本地的最后修改时间

                ·随后服务器对比这个资源的最后修改时间与If-Modified-Since,如果缓存的最后修改时间是最后修改时间,则返回一个304状态码,告诉浏览器可以使用本地缓存,并且附上Last-Modified字段,表示这个资源在服务器的最后修改时间

                · 如果发现服务器端的资源最近被修改过,则返回一个200 OK,并且带上该资源

                还有一种方法是通过请求头部的IF-None_Match和响应头部中的ETag字段

                ETag是标识唯一资源的一个值,当资源过期时,浏览器发现响应头里有 Etag,则再次向服务器发起请求时,会将请求头 If-None-Match 值设置为 Etag 的值。服务器收到请求后进行比对,如果资源没有变化返回 304,如果资源变化了返回 200。

        这两种方式有什么不同呢,第一种实现方式是基于时间实现的,第二种实现方式是基于一个唯一标识实现的,相对来说后者可以更加准确地判断文件内容是否被修改,避免由于时间篡改导致的不可靠问题。

        另外,ETag的优先级要高于Last-Modified,先判断Etag,再比较Last-Modified

        因为 ETag 主要能解决 Last-Modified 几个比较难以解决的问题:

        1. 在没有修改文件内容的情况下,文件的最后修改时间也可能会改变,Last-Modified可能会误判文件被修改了

        2. If-Modified-Since 的查询粒度是秒级的,而Etag是原子级的

        3. 有些服务器不能精确获取文件的最后修改时间

        注意!协商缓存是再强制缓存没有成功下才会使用!

HTTP/1.1

        优点

        1. 简单

       HTTP的基本报文就是 头部+内容,而头部中包含的也都是一些键值字段,易于理解和学习

        2. 可拓展性

        HTTP虽然由RFC文档给出的官方推荐语义,但是在实际开发中都可以自定义和补充

        另外HTTP工作在应用层,更具体的是在OSI的应用层,下层可以随意扩展和开发

        - HTTPS在HTTP和TCP之间加入了SSL/TLS安全层

        - HTTP/3.0使用UDP

        3. 管道传输

        由于采用了持续连接,就可以实现管道传输(pipeline),客户端可以连续发出请求,而不等前面的请求被回应,这解决了客户端的队头阻塞;但是服务器一侧还是得按照接受请求的顺序来响应,所以服务器的队头阻塞没有解决

        但是HTTP/1.1的管道传输不是默认开启的,并且浏览器基本都没有支持,很可惜!

        缺点

        1. 明文传输

        HTTP信息的传输并没有经过加密,相当于裸奔,用一些抓包工具随随便便就可以抓取这些信息,相当不安全,如果其中包含了账号密码信息,则会导致一些相当严重的后果!

        2. 不验证服务端身份

        HTTP并不验证访问方的权威性,只处理你的请求并向目标发出请求,想象如果有一些盗版网站甚至恶意网站(假淘宝),岂不是很危险!

        3. 不验证报文的正确性

        HTTP请求的报文可能被篡改,到服务器后服务器处理被篡改的请求,导致问题的出现;响应报文也可能被篡改,比较经典的例子就是在网页响应时,第三方截取了,并在其中植入垃圾广告,客户端看到的就是很糟糕的画面了

HTTP/1.1优化

        1. 减少重定向次数(见Wed缓存处)

        2. 合并资源,例如使用CSS技术,将要请求的许多图片合成一个大图片,再由浏览器进行解析        

        3. 延迟发送请求,请求网页的时候,没必要把全部资源都获取到,而是只获取当前用户所看到的页面资源,当用户向下滑动页面的时候,再向服务器获取接下来的资源,这样就达到了延迟发送请求的效果——按需获取

        4. 压缩数据

 

HTTPS

       HTTP与HTTPS区别

        1. HTTPS为了解决明文传输问题,加入了SSL/TLS层,用以保证通信的安全性

        2. HTTP默认端口80,HTTPS默认端口443

        3. HTTPS要向CA申请数字证书,来保证服务器的身份是可信的

        HTTPS的安全保障

        - 摘要算法

                HTTPS用双方商量好的哈希算法来计算出所传输内容的一个[摘要],用来判断内容是否被篡改!

        - 混合加密

                对称加密+非对称加密

        非对称加密采用一个公钥和一个私钥,这两个密钥都可以双向解密

        - 公钥加密,私钥解密。这个目的是为了保证内容传输的安全,因为被公钥加密的内容,其他人是无法解密的,只有持有私钥的人,才能解密出实际的内容;

        - 私钥加密,公钥解密。这个目的是为了保证消息不会被冒充,因为私钥是不可泄露的,如果公钥能正常解密出私钥加密的内容,就能证明这个消息是来源于持有私钥身份的人发送的。

        其实就是数字签名(解密摘要算法算出的哈希值)

        - 数字证书

                通过前面的摘要算法和混合加密过程,能够保证数据的完整性和可靠性,但是万一有人能够伪造公私钥呢?这就需要一个官方权威的人来管理这个身份

        HTTPS中的数字证书是权威机构颁发给一些官方网站的证书,用来确保请求的服务器是官方的,从而解决了上面提到的“访问了假的淘宝”的问题

        在客户端的浏览器或者操作系统中会内置一个CA公钥,用于验证数字证书

        SSL/TLS建立过程

        · 客户端向服务器索要并验证服务器的公钥

        · 双方协商生产一个用于本次通话的 密钥

        · 双方采用这个商量出来的 密钥 进行加密通信

        - 客户端在TCP连接建立后,向服务器发送ClientHello请求,包含了客户端支持的SSL/TLS协议版本,一个随机数A(用于产生密钥),一套自己支持的加密算法

        - 服务器收到这个请求后,回应ServerHello,确认SSL/TLS协议版本,如果不支持,则关闭此次通信,另外包含了一个随机数B(同样用于产生密钥),确认加密算法,以及该服务器的数字证书

        - 客户端收到这个回应后,先在浏览器或操作系统中核对该数字证书的真实性,如果真实则从数字证书中取出服务器的公钥,然后用它来加密报文,再产生一个随机数C(被公钥加密),加入信息加密通知,表明此后传输的信息都是经过加密的,并且将这些信息都做摘要算法

        - 上述过程中产生了三个随机数,这样双方就都用协商的加密算法生成此次的会话密钥

        -- 最后服务器向客户端发送加密通信算法改变通知,表示接下来的信息都会通过会话密钥进行加密,并发送握手结束通知,这些数据也都会被摘要算法

        最后,HTTPS在传输过程中也会分片,并且进行压缩,会对每个被压缩的片段加入摘要算法算出的值,然后进行加密,最后拼上头部信息,送入TCP传输层

        思考:HTTPS真的安全吗,客户端通过浏览器向服务端发起 HTTPS 请求时,被「假基站」转发到了一个「中间人服务器」,于是客户端是和「中间人服务器」完成了 TLS 握手,然后这个「中间人服务器」再与真正的服务端完成 TLS 握手 

        - 中间人证书?恶意病毒植入伪造证书?

        为什么抓包程序能明文看到HTTPS的数据

        这个抓包程序作为中间人,它在被你安装到计算机上时,它自身的证书就被你信任了

HTTP/2

        1. HTTP/2是基于HTTPS的,达成了安全性的目标

        2. 用Stream的概念,采用StreamID可以乱序发送并组装,实现了多路复用(在一个 TCP 连接里,服务器收到了客户端 A 和 B 的两个请求,如果发现 A 处理过程非常耗时,于是就回应 A 请求已经处理好的部分,接着回应 B 请求,完成后,再回应 A 请求剩下的部分)——也就是并发传输,解决了队头阻塞的问题

        3. 二进制格式传输(以帧的形式发送),比如状态码200,HTTP/1.1以'2' '0' '0'三个字节表示,而HTTP/2.0用一个字节的10001000表示

        4. 服务器推送,改变了传统的客户端-服务器的请求-应答机制,服务器可以主动向客户端发送消息,其中客户端建立的StreamID是奇数,服务端建立的StreamID是偶数。

        - 有了服务器推送,可以实现服务器对于一些连带的服务,可以由第一个客户端的请求,将连带的内容一并推送过去(客户端请求一部手机的内容,服务器不仅仅推送这部手机的内容,还把下单的内容等推送给客户端)

        但是多个 HTTP 请求在复用一个 TCP 连接,下层的 TCP 协议是不知道有多少个 HTTP 请求的。所以一旦发生了丢包现象,就会触发 TCP 的重传机制,这样在一个 TCP 连接中的所有的 HTTP 请求都必须等待这个丢了的包被重传回来。HTTP已经做得很好了,但是无法解决这个问题,这都是基于 TCP 传输层的问题

        总结来说就是,HTTP/2解决了应用层的队头阻塞问题,但是传输层的队头阻塞无法解决!

        所以 HTTP/3 把 HTTP 下层的 TCP 协议改成了 UDP!

HTTP/3 

        1.解决队头阻塞

        HTTP/3.0为了改善HTTP/2.0的队头阻塞,将传输层改成了UDP协议

        并且为了保证数据的可靠性传输,在UDP的基础上封装了 QUIC协议 

        QUIC 协议也有类似 HTTP/2 Stream 与多路复用的概念,也是可以在同一条连接上并发传输多个 Stream,Stream 可以认为就是一条 HTTP 请求。

        QUIC 有自己的一套机制可以保证传输的可靠性的。当某个流发生丢包时,只会阻塞这个流,其他流不会受到影响,因此不存在队头阻塞问题。这与 HTTP/2 不同,HTTP/2 只要某个流中的数据包丢失了,其他流也会因此受影响。

        所以,QUIC 连接上的多个 Stream 之间并没有依赖,都是独立的,某个流发生丢包了,只会影响该流,其他流不受影响。

         2. 连接建立更快

        对于 HTTP/1 和 HTTP/2 协议,TCP 和 TLS 是分层的,分别属于内核实现的传输层、openssl 库实现的表示层,因此它们难以合并在一起,需要分批次来握手,先 TCP 握手,再 TLS 握手。

        HTTP/3 在传输数据前虽然需要 QUIC 协议握手,但是这个握手过程只需要 1 RTT,握手的目的是为确认双方的「连接 ID」,连接迁移就是基于连接 ID 实现的。

        但是 HTTP/3 的 QUIC 协议并不是与 TLS 分层,而是 QUIC 内部包含了 TLS,它在自己的帧会携带 TLS 里的“记录”,再加上 QUIC 使用的是 TLS/1.3,因此仅需 1 个 RTT 就可以「同时」完成建立连接与密钥协商

        3. 连接迁移

        基于 TCP 传输协议的 HTTP 协议,由于是通过四元组(源 IP、源端口、目的 IP、目的端口)确定一条 TCP 连接。那么当移动设备的网络从 4G 切换到 WIFI 时,意味着 IP 地址变化了,那么就必须要断开连接,然后重新建立连接。而建立连接的过程包含 TCP 三次握手和 TLS 四次握手的时延,以及 TCP 慢启动的减速过程,给用户的感觉就是网络突然卡顿了一下,因此连接的迁移成本是很高的。

        QUIC通过连接ID来标记通信的两个端点,客户端和服务器可以各自选择一组 ID 来标记自己,因此即使移动设备的网络变化后,导致 IP 地址变化了,只要仍保有上下文信息(比如连接 ID、TLS 密钥等),就可以“无缝”地复用原连接,消除重连的成本,没有丝毫卡顿感,达到了连接迁移的功能。

        所以, QUIC 是一个在 UDP 之上的 TCP + TLS + HTTP/2 的多路复用的协议。

        但是!新协议的部署是一个很难的问题!!

        因此HTTP/3.0的普及还有待观察!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值