发布时间:2023-09-08 12:00
HTTP 协议一般指 HTTP(超文本传输协议)。是一种用于分布式、协作式和超媒体信息系统的应用层协议,是因特网上应用最为广泛的一种网络传输协议,所有的 WWW 文件都必须遵守这个标准。HTTP 是为 Web 浏览器与 Web 服务器之间的通信而设计的,但也可以用于其他目的。HTTP 是一个基于 TCP/IP 通信协议来传递数据的(HTML 文件、图片文件、查询结果等)。
DNS 把域名解析成IP
1、先检查本地host文件,如果有对应的规则就取;
2、如果没有,发出一个 DNS请求到本地DNS服务器;
3、本地DNS服务器会检查缓存中有没有记录,有就返回;
4;本地DNS服务器向DNS根服务器查询,如果没有DNS根服务器查询会叫本地DNS服务器到域服务器;
5、本地DNS服务器像域服务器发出请求,域服务器会告诉本地DNS服务解析服务器的地址;
6、本地DNS服务向域名的解析服务器发出请求,这时就能收到一个域名和IP地址对应关系,本地DNS服务器不仅要把IP地址返回给用户电脑,还要把这个对应关系保存在缓存中
客户端和服务端通过三次握手建立TCP连接,然后发送请求
服务端处理请求并响应结果
客户端接收到结果并开始解析
1、创建dom树;
2、解析css,生成css规则树;
3、根据dom树和css样式表,生成render树;
4、浏览器根据dom树布局,把每个树节点确定在特定的位置上;
5、调用dom节点的paint方法,绘制页面元素;
6、浏览器会将各层的信息发给GPU,GPU会把各层合成
HTTP/1.1 最大的变化就是引入了持久连接(persistent connection),在HTTP/1.1中默认开启 Connection: keep-alive,即TCP连接默认不关闭,可以被多个请求复用。
那么管道机制就是在同一个TCP连接中可以同时发送多个HTTP请求而不用等待上一个请求返回数据后,再发送下一个请求。虽然可以同时发送多个HTTP请求,但是服务器响应是按照请求的顺序进行响应的。
HTTP 2.0的多路复用是在同一个TCP连接中,可以发送多个HTTP请求,而且请求的响应不依赖于前一个请求。每个请求单独处理,不会出现HTTP1.1中上一个请求没有回应便一直等待的情况。
举例来说,在一个TCP连接里面,服务器同时收到了A请求和B请求,于是先回应A请求,结果发现处理过程非常耗时,于是就发送A请求已经处理好的部分, 接着回应B请求,完成后,再发送A请求剩下的部分。
它们的本质都是 TCP 链接,并无区别。但是由于 HTTP 的规定以及浏览器/服务器的限制,导致它们在应用过程中可能会有所不同。
常见缓存响应指令:
Accept:通知服务器,用户代理能够处理的媒体类型及媒体类型的相对优先级。文本、图片、视频、二进制等类型,如application/json,text/plain, */*
Content-Type:表示媒体类型信息。它被用来告诉服务端如何处理请求的数据,以及告诉客户端(如何解析响应的数据,比如解析html、图片、文本
application/json;参数会被直接放到请求实体里,不进行任何处理。服务端/客户端会按json格式解析数据
multipart/form-data;多用于文件上传,表单数据都保存在http的正文部分
application/x-www-form-urlencoded;不支持文件,一般用于表单提交
Range:实体主体的位置范围,一般用于发出部分请求时使用;例如bytes: 5001-10000;响应首部字段为Content-Range: bytes 5001-10000/10000
Host:服务器的域名/IP地址和端口号(可选);它会告知服务器请求的资源所处的互联网主机名和端口号。他是HTTP/1.1规范内是唯一一个必须被包含在请求内的首部字段。它与单台服务器分配多个域名的虚拟主机的工作机制有很密切的关联,这是首部字段Host必须存在的意义。
Referer:当前请求页面的来源页面的地址;包括协议、域名、端口还包括路径,参数,注意不包括hash值。可用作防盗链。注意: referer 实际上是 “referrer” 误拼写。
Origin:指示了请求来自于哪个站点。协议+域名+端口号(可选),该首部用于 CORS 请求或者 POST 请求
区别: host是请求的服务器域名/ip等信息,referer是表明请求来自哪个地址。referer和origin作用相似,origin不包含路径信息,只有跨域请求,或者同域时发送post请求才会携带
Expires:响应头,代表该资源的过期时间
Cache-Control:请求/响应头,缓存控制字段,精确控制缓存策略
If-Modified-Since:请求头,资源最近修改时间,由浏览器告诉服务器
Last-Modified:响应头,资源最近修改时间,由服务器告诉浏览器
Etag:响应头,资源标识,由服务器告诉浏览器
If-None-Match:请求头,缓存资源标识,由浏览器告诉服务器
ETag 有强弱之分
强 ETag 要求资源在字节级别必须完全相符
弱 ETag 在值前有个“W/”标记,只要求资源在语义上没有变化,但内部可能会有部分发生了改变(例如 HTML 里的标签顺序调整,或者多了几个空格)
缓存首部字段详情
为了准确无误地将数据送达目标处,TCP协议采用了\"三次握手\"策略。用TCP协议把数据包送出去后,TCP不会对传送后的情况置之不理,它一定会向对方确认是否成功送达。
握手过程过程中使用了TCP的标识,SYN(synchronize - 同步请求)和ACK(acknowledgement - 确认同步)
1)发送端首先发送一个带SYN标志的数据包给对方。
2)接收端收到后,回传一个带有SYN/ACK标志的数据包以示传达确认信息。
3)最后,发送端再回传一个带ACK标志的数据包,代表“握手”结束。
若在握手过程中某个阶段莫名中断,TCP协议会再次以相同的顺序发送相同的数据包。
详情:
(1)首先客户端向服务器端发送一段TCP报文,其中:
标记位为SYN,表示“请求建立新连接”;
序号为Seq=X(X一般为1);
随后客户端进入SYN-SENT阶段。
(2)服务器端接收到来自客户端的TCP报文之后,结束LISTEN阶段。并返回一段TCP报文,其中:
标志位为SYN和ACK,表示“确认客户端的报文Seq序号有效,服务器能正常接收客户端发送的数据,并同意创建新连接”(即告诉客户端,服务器收到了你的数据);
序号为Seq=y;
确认号为Ack=x+1,表示收到客户端的序号Seq并将其值加1作为自己确认号Ack的值;随后服务器端进入SYN-RCVD阶段。
(3)客户端接收到来自服务器端的确认收到数据的TCP报文之后,明确了从客户端到服务器的数据传输是正常的,结束SYN-SENT阶段。并返回最后一段TCP报文。其中:
标志位为ACK,表示“确认收到服务器端同意连接的信号”(即告诉服务器,我知道你收到我发的数据了);
序号为Seq=x+1,表示收到服务器端的确认号Ack,并将其值作为自己的序号值;
确认号为Ack=y+1,表示收到服务器端序号Seq,并将其值加1作为自己的确认号Ack的值;
随后客户端进入ESTABLISHED阶段。
服务器收到来自客户端的“确认收到服务器数据”的TCP报文之后,明确了从服务器到客户端的数据传输是正常的。结束SYN-SENT阶段,进入ESTABLISHED阶段。
在客户端与服务器端传输的TCP报文中,双方的确认号Ack和序号Seq的值,都是在彼此Ack和Seq值的基础上进行计算的,这样做保证了TCP报文传输的连贯性。一旦出现某一方发出的TCP报文丢失,便无法继续\"握手\",以此确保了\"三次握手\"的顺利完成。
为什么需要三次握手而不是两次?
为了防止服务器端开启一些无用的连接增加服务器开销以及防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。
由于网络传输是有延时的(要通过网络光纤和各种中间代理服务器),在传输的过程中,比如客户端发起了SYN=1创建连接的请求(第一次握手)。
如果服务器端就直接创建了这个连接并返回包含SYN、ACK和Seq等内容的数据包给客户端,这个数据包因为网络传输的原因丢失了,丢失之后客户端就一直没有接收到服务器返回的数据包。
客户端可能设置了一个超时时间,时间到了就关闭了连接创建的请求。再重新发出创建连接的请求,而服务器端是不知道的,如果没有第三次握手告诉服务器端客户端收的到服务器端传输的数据的话,
服务器端是不知道客户端有没有接收到服务器端返回的信息的。
这样没有给服务器端一个创建还是关闭连接端口的请求,服务器端的端口就一直开着,等到客户端因超时重新发出请求时,服务器就会重新开启一个端口连接。那么服务器端上没有接收到请求数据的上一个端口就一直开着,长此以往,这样的端口多了,就会造成服务器端开销的严重浪费。
还有一种情况是已经失效的客户端发出的请求信息,由于某种原因传输到了服务器端,服务器端以为是客户端发出的有效请求,接收后产生错误。
所以我们需要“第三次握手”来确认这个过程,让客户端和服务器端能够及时地察觉到因为网络等一些问题导致的连接创建失败,这样服务器端的端口就可以关闭了不用一直等待。
也可以这样理解:“第三次握手”是客户端向服务器端发送数据,这个数据就是要告诉服务器,客户端有没有收到服务器“第二次握手”时传过去的数据。若发送的这个数据是“收到了”的信息,接收后服务器就正常建立TCP连接,否则建立TCP连接失败,服务器关闭连接端口。由此减少服务器开销和接收到失效请求发生的错误。
(1)首先客户端想要释放连接,向服务器端发送一段TCP报文,其中:
标记位为FIN,表示“请求释放连接“;
序号为Seq=U;
随后客户端进入FIN-WAIT-1阶段,即半关闭阶段。并且停止在客户端到服务器端方向上发送数据,但是客户端仍然能接收从服务器端传输过来的数据。
注意:这里不发送的是正常连接时传输的数据(非确认报文),而不是一切数据,所以客户端仍然能发送ACK确认报文。
(2)服务器端接收到从客户端发出的TCP报文之后,确认了客户端想要释放连接,随后服务器端结束ESTABLISHED阶段,进入CLOSE-WAIT阶段(半关闭状态)并返回一段TCP报文,其中:
标记位为ACK,表示“接收到客户端发送的释放连接的请求”;
序号为Seq=V;
确认号为Ack=U+1,表示是在收到客户端报文的基础上,将其序号Seq值加1作为本段报文确认号Ack的值;
随后服务器端开始准备释放服务器端到客户端方向上的连接。
客户端收到从服务器端发出的TCP报文之后,确认了服务器收到了客户端发出的释放连接请求,随后客户端结束FIN-WAIT-1阶段,进入FIN-WAIT-2阶段
前\"两次挥手\"既让服务器端知道了客户端想要释放连接,也让客户端知道了服务器端了解了自己想要释放连接的请求。于是,可以确认关闭客户端到服务器端方向上的连接了
(3)服务器端自从发出ACK确认报文之后,经过CLOSED-WAIT阶段,做好了释放服务器端到客户端方向上的连接准备,再次向客户端发出一段TCP报文,其中:
标记位为FIN,ACK,表示“已经准备好释放连接了”。注意:这里的ACK并不是确认收到服务器端报文的确认报文。
序号为Seq=W;
确认号为Ack=U+1;表示是在收到客户端报文的基础上,将其序号Seq值加1作为本段报文确认号Ack的值。
随后服务器端结束CLOSE-WAIT阶段,进入LAST-ACK阶段。并且停止在服务器端到客户端的方向上发送数据,但是服务器端仍然能够接收从客户端传输过来的数据。
(4)客户端收到从服务器端发出的TCP报文,确认了服务器端已做好释放连接的准备,结束FIN-WAIT-2阶段,进入TIME-WAIT阶段,并向服务器端发送一段报文,其中:
标记位为ACK,表示“接收到服务器准备好释放连接的信号”。
序号为Seq=U+1;表示是在收到了服务器端报文的基础上,将其确认号Ack值作为本段报文序号的值。
确认号为Ack=W+1;表示是在收到了服务器端报文的基础上,将其序号Seq值作为本段报文确认号的值。
随后客户端开始在TIME-WAIT阶段等待2MSL
为什么要客户端要等待2MSL呢?见后文。
服务器端收到从客户端发出的TCP报文之后结束LAST-ACK阶段,进入CLOSED阶段。由此正式确认关闭服务器端到客户端方向上的连接。
客户端等待完2MSL之后,结束TIME-WAIT阶段,进入CLOSED阶段,由此完成“四次挥手”。
后“两次挥手”既让客户端知道了服务器端准备好释放连接了,也让服务器端知道了客户端了解了自己准备好释放连接了。于是,可以确认关闭服务器端到客户端方向上的连接了,由此完成“四次挥手”。
与“三次挥手”一样,在客户端与服务器端传输的TCP报文中,双方的确认号Ack和序号Seq的值,都是在彼此Ack和Seq值的基础上进行计算的,这样做保证了TCP报文传输的连贯性,一旦出现某一方发出的TCP报文丢失,便无法继续\"挥手\",以此确保了\"四次挥手\"的顺利完成。
为什么“握手”是三次,“挥手”却要四次?
TCP建立连接时之所以只需要\"三次握手\",是因为在第二次\"握手\"过程中,服务器端发送给客户端的TCP报文是以SYN与ACK作为标志位的。SYN是请求连接标志,表示服务器端同意建立连接;ACK是确认报文,表示告诉客户端,服务器端收到了它的请求报文。
即SYN建立连接报文与ACK确认接收报文是在同一次\"握手\"当中传输的,所以\"三次握手\"不多也不少,正好让双方明确彼此信息互通。
TCP释放连接时之所以需要“四次挥手”,是因为FIN释放连接报文与ACK确认接收报文是分别由第二次和第三次\"握手\"传输的。为何建立连接时一起传输,释放连接时却要分开传输?
建立连接时,被动方服务器端结束CLOSED阶段进入“握手”阶段并不需要任何准备,可以直接返回SYN和ACK报文,开始建立连接。
释放连接时,被动方服务器,突然收到主动方客户端释放连接的请求时并不能立即释放连接,因为还有必要的数据需要处理,所以服务器先返回ACK确认收到报文,经过CLOSE-WAIT阶段准备好释放连接之后,才能返回FIN释放连接报文。
所以是“三次握手”,“四次挥手”。
详情文章
发送窗口就是一个循环利用的缓冲区,应用层发送数据,就是往缓冲区中写入数据。收到ACK后,就相当于从缓冲区中移除数据,不过并不会真正移除数据,只需要后移对应的指针就可以了。
应用层会将数据写入到缓冲区中,当超过缓冲区的最大地址后,就循环利用头部,覆盖头部的数据。
发送缓冲区分为四个部分:
1、已经收到ack包的数据
已经收到ack包的数据,代表接收窗口已经接收了对应的数据,可以被新数据覆盖。
2、已经发送还未接收到ack包的数据
已经发送出去,但是还未收到接收方对应的ack包
3、允许发送但是还未发送的数据
允许发送但是还未发送的数据。
4、不允许发送的数据。
发送窗口之外的数据,排队等待后续发送。
接收窗口:
接收窗口也是存在于操作系统中开辟的一块缓冲区,用于接收数据。缓冲区本质是一个循环数组的实现。利用两个指针来维护相关的区域。
接收窗口存在于一个循环利用的缓冲区,接收数据 就是往缓冲区中写入数据。应用层读取数据后,就相当于从缓冲区中移除数据,不过并不会真正移除数据,只需要后移对应的指针就可以了。
当数据写入超过缓冲区的最大地址后,就循环利用头部,覆盖头部的数据。
缓冲区分为三部分:
1、应用层已经读取的数据
已经接收到的数据,并且已经发送了ack包,并且已经被应用层读取。
2、接收窗口中的数据
接收窗口中存储的是当前允许被接收的数据。
接收窗口允许无序接收数据包,所以接收窗口中有一部分数据接收到了,一部分没接收到,将无序的数据包直接缓存到接收窗口中。
因为无序的接收数据包,接收窗口中是存在空隙的,因为先发送的数据包由于网络原因,反而可能会后到接收方。
当数据包缓存到接收窗口中,就会返回ack包,ack包中会携带SACK信息,也就是选择重选信息。
3、还未收到的数据
还不能接收数据的区域,也就是接收窗口之外的数据。
TCP滑动窗口详解
https详解
1)、客户端发起 HTTPS 请求
这个没什么好说的,就是用户在浏览器里输入一个 https 网址,然后连接到 server 的 443 端口。
2)、服务端的配置
采用 HTTPS 协议的服务器必须要有一套数字证书,可以自己制作,也可以向组织申请,区别就是自己颁发的证书需要客户端验证通过,才可以继续访问,而使用受信任的公司申请的证书则不会弹出提示页面(startssl 就是个不错的选择,有 1 年的免费服务)。
这套证书其实就是一对公钥和私钥,如果对公钥和私钥不太理解,可以想象成一把钥匙和一个锁头,只是全世界只有你一个人有这把钥匙,你可以把锁头给别人,别人可以用这个锁把重要的东西锁起来,然后发给你,因为只有你一个人有这把钥匙,所以只有你才能看到被这把锁锁起来的东西。
3)、传送证书
这个证书其实就是公钥,只是包含了很多信息,如证书的颁发机构,过期时间等等。
4)、客户端解析证书
这部分工作是有客户端的TLS来完成的,首先会验证公钥是否有效,比如颁发机构,过期时间等等,如果发现异常,则会弹出一个警告框,提示证书存在问题。
如果证书没有问题,那么就生成一个随机值,然后用证书对该随机值进行加密,就好像上面说的,把随机值用锁头锁起来,这样除非有钥匙,不然看不到被锁住的内容。
5)、传送加密信息
这部分传送的是用证书加密后的随机值,目的就是让服务端得到这个随机值,以后客户端和服务端的通信就可以通过这个随机值来进行加密解密了。
6)、服务端解密信息
服务端用私钥解密后,得到了客户端传过来的随机值(私钥),然后把内容通过该值进行对称加密,所谓对称加密就是,将信息和私钥通过某种算法混合在一起,这样除非知道私钥,不然无法获取内容,而正好客户端和服务端都知道这个私钥,所以只要加密算法够彪悍,私钥够复杂,数据就够安全。
7)、传输加密后的信息
这部分信息是服务段用私钥加密后的信息,可以在客户端被还原。
8)、客户端解密信息
客户端用之前生成的私钥解密服务段传过来的信息,于是获取了解密后的内容,整个过程第三方即使监听到了数据,也束手无策。
cookie和session都是用来跟踪浏览器用户身份的会话方式。
数据存放位置不同:cookie数据存放在客户的浏览器上,session数据放在服务器上。
安全程度不同:cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,考虑到安全应当使用session。
性能不同:session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用cookie。
数据存储大小不同:单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie,而session则存储与服务端,浏览器对其没有限制。
HTTP是无状态协议,它不对之前发生的请求和响应的状态进行管理。也就是说,无法根据之前的状态进行本次的请求处理。
比如登录后页面跳转为了保持登录状态可以用两种方式记录状态①每次跳转都要再次登录(无法接受)②在请求报文中附加参数来管理登录状态。(cookie由此而来)
Cookie会根据从服务器端发送的响应报文内的一个叫做Set-Cookie
的首部字段信息,通知客户端保存Cookie。当下次客户端再往该服务器发送请求时,客户端会自动在请求报文中加入Cookie值后发送出去。服务器端发现客户端发送过来的Cookie后,会去检查究竟是从哪一个客户端发来的连接请求,然后对比服务器上的记录,最后得到之前的状态信息。
set-cookie字段属性:
浏览器缓存通过 HTTP/HTTPS 实现,存储位置有四种: