这个问题是检验web和计网学习程度的经典问题。
网站访问流程:
1.域名->ip地址
1) 在输入完一个域名之后,首先是检查浏览器自身的DNS缓存是否有相应IP地址映射,如果没有对应的解析记录,浏览器会查找本机的hosts配置文件(一般是C:\Windows\System32\drivers\etc\hosts,这个文件是用于在操作系统级别上主机名和IP地址的映射。在这个文件中,可以手动添加自定义的主机名和对应的IP地址,当操作系统进行域名解析时,会首先查找hosts文件,如果找到匹配的主机名,就会直接使用对应的IP地址进行访问,而不再通过DNS进行解析)。
hosts文件中的映射关系优先级比DNS解析高。如果在hosts文件中有映射关系,浏览器会直接使用该映射关系中的IP地址进行访问
2) 如果以上都没有查到,才进行DNS解析。
a.在进行DNS解析时,首先会检查本地DNS缓存中是否存在对应的解析结果。如果已经存在,则直接使用缓存中的结果,不再向远程DNS服务器发送查询请求。
如果本地DNS服务器缓存中没有对应的解析记录,则本地DNS服务器会向根DNS服务器发起递归查询请求。
- Windows DNS客户端服务会在解析域名时自动将域名解析的结果存储在本地DNS缓存中,以便在后续的请求中能够快速获取解析结果,提高解析的速度和效率。存储在本地DNS缓存中的解析记录包括域名和对应的IP地址。本地DNS缓存的域名解析记录存储在Windows DNS客户端服务(DNS Client Service)管理的缓存数据库中,不是一个特定的文件。该缓存位于系统内存中,而不是磁盘上的文件。
- 解析记录的存储时间是有限的,具体的存活时间由服务器的TTL(Time-to-Live)时间决定。TTL是DNS服务器在返回解析结果时附加的一个时间值,表示该解析结果的有效生命周期。一般情况下,解析记录的存活时间为TTL值减去DNS查询的耗时。
- 当解析记录的存活时间过期后,下一次需要解析该域名时,DNS客户端服务会重新发送解析请求给DNS解析器,并更新本地DNS缓存中的解析记录。因此,本地DNS缓存中的解析记录是动态的,会根据TTL值进行自动更新。
- Windows系统中,可以通过命令行ipconfig /displaydns执行以下命令来显示本地DNS缓存的详细信息:
b.如果本地DNS服务器缓存中没有对应的解析记录,浏览器会向由你的网络服务提供商(ISP,如中国移动中国电信等)提供的DNS服务器发起解析请求(除了ISP提供,也可以是组织内部建立的DNS服务器),传递需要解析的域名给这个DNS服务器。
- 这个DNS服务器称为本地DNS服务器,它是用户主机在进行域名解析时的第一站,它会查找自己的缓存,看是否存在对应的解析记录,如果没有,则本地DNS服务器会向根DNS服务器发起递归查询请求。
- 根DNS服务器是互联网域名系统(DNS)的最高层级服务器,它存储了所有顶级域名(如.com、.net、.org等)的DNS记录。根DNS服务器的作用是将域名解析请求转发到下一级的DNS服务器。本地DNS服务器将结果返回给用户主机,用户主机操作系统接收到DNS解析器返回的结果后,将结果存储到本地DNS缓存中,并将IP地址返回给浏览器。
- 完成域名解析过程。
2.浏览器根据解析得到的IP地址,与服务器建立TCP连接
浏览器通过DNS解析获取到目标服务器的IP地址之后,使用TCP的三次握手来确保连接的可靠性。
- 浏览器向目标服务器发起连接请求(SYN包),其中包含自己的初始序列号。
- 目标服务器接收到连接请求后,会回复一个确认连接请求的ACK包,其中包含自己的初始序列号和对浏览器初始序列号的确认。
- 浏览器收到目标服务器的ACK包后,会向目标服务器发送一个确认ACK包,同时会发送自己所期望的下一个序列号。
- 目标服务器收到浏览器的确认ACK包后,连接建立成功,可以开始进行数据传输。
浏览器 目标服务器 -------------- SYN包 --------------> <--------------ACK包 (对SYN的确认,以及自己的序列号) -------------- ACK包 -------------->
三次握手的目的是确保双方都能正确接收到对方的连接请求和确认,以建立一个可靠的连接。在握手过程中,双方交换了初始序列号,这是为了后续的数据传输进行序列号的管理和确认。
-
思考:三次握手是什么,为什么吗,为什么不多或者少次数?
为什么不是两次?
防止已失效的连接请求被服务器接受:如果握手只进行两次,客户端发出的连接请求可能会在网络中因为延迟而被延迟到达服务器,而服务器此时可能会误认为该连接请求是新的有效请求而接受,从而导致资源浪费。通过第三次握手,服务器可以确认客户端确实发送了连接请求,并且是之前没有成功建立连接的请求,从而避免了上述情况。
如果只进行两次握手,客户端发出连接请求后,服务器已经接受并且发送了确认,此时连接就会建立起来。但是可能因为网络问题,客户端并没有收到服务器发出的确认,此时客户端可能会错误地认为连接已经建立成功,开始向服务器发送数据。但是,由于服务器并没有收到连接请求的确认,服务器会拒绝接受这些数据。
2.为什么不是更多次?更多次会更安全可靠吗?
增加TCP连接握手的次数并不一定会使连接更加可靠和安全。在基于TCP的网络通信中,通过三次握手已经可以提供足够的可靠性和安全性,再增加握手的次数可能带来以下问题:
延迟:每次握手都需要一定的时间,多次握手意味着增加了连接建立的时间。这会导致连接建立的延迟,尤其是在高延迟的网络环境中。
资源消耗:更多的握手意味着更多的资源消耗,包括计算资源和网络带宽。这可能会对系统性能和网络负载产生不利影响。
可扩展性差:如果连接过程需要更多的握手,对于网络中的大量并发连接来说,可能会导致连接请求超时、资源耗尽和连接失败等问题。
此外,增加握手次数并不能完全解决网络安全问题。握手过程主要用于建立连接,而不是用于加密和认证数据的安全传输。在实际应用中,通常需要使用其他的安全机制,如TLS/SSL来加密数据和进行身份验证。TCP连接采用三次握手是为了在保持较高性能和较低延迟的同时提供基本的可靠性和安全性,不是通过增加握手次数来提高可靠性和安全性。
3.建立连接后,浏览器发送请求,服务器处理请求
建立连接后,用户的请求会发送给本地网络中的网关设备,网关会根据目标服务器的IP地址和本地网络的路由表来选择到达目标服务器的下一跳。网关会检查请求的目标IP地址,然后查找本地网络的路由表,确定该请求需要通过哪个接口发送出去,经过一系列路由的选择,最终到达目标服务器(当用户主机与服务器位于同一个局域网或子网中时,用户主机可以直接与服务器建立连接,不需要经过网关或路由器。在这种情况下,用户主机会通过ARP(Address Resolution Protocol,地址解析协议)获取目标服务器的MAC地址,直接发送数据包到目标服务器)。
请求包括:
- 请求方法(Get,Post,HEAD,DELETE,PUT,TRACT…)
- 请求URL(包含主机名、路径等)
- 请求头部(包括用户代理、语言、内容类型、Cookie等)
- 请求正文(POST请求时包含表单数据等)
Accept: //告诉服务器它所支持的数据类型
Accept-Encoding: //支持哪种编码格式:GBK,UTF-8,GB2312,ISO8859-1
Accept-Language: //告诉服务器它的语言环境
Cache-Control: //缓存控制
Connection: //告诉服务器,请求完成是断开还是保持连接
HOST: //主机
...
思考:GET和POST请求区别?
GET:一次请求可以携带的参数比较少,大小有限制,会在浏览器的URL地址栏显示数据内容,不安全,但高效。
POST:一次请求可以携带的参数没有限制,大小没有限制,不会在浏览器的URL地址栏显示数据内容,安全,但不高效。TCP就像汽车,我们用TCP来运输数据,它很可靠,从来不会发生丢件少件的现象。但是如果路上跑的全是看起来一模一样的汽车,那这个世界看起来是一团混乱,送急件的汽车可能被前面满载货物的汽车拦堵在路上,整个交通系统一定会瘫痪。为了避免这种情况发生,交通规则HTTP诞生了。HTTP给汽车运输设定了好几个服务类别,有GET, POST, PUT, DELETE等等一共8类,HTTP规定,当执行GET请求的时候,要给汽车贴上GET的标签(设置method为GET),而且要求把传送的数据放在车顶上(url中)以方便记录。如果是POST请求,就要在车上贴上POST的标签,并把货物放在车厢里。
还有另一个重要的角色:运输公司。不同的浏览器(发起http请求)和服务器(接受http请求)就是不同的运输公司。 虽然理论上,你可以在车顶上无限的堆货物(url中无限加参数)。但是运输公司可不傻,装货和卸货也是有很大成本的,他们会限制单次运输量来控制风险,数据量太大对浏览器和服务器都是很大负担。如果你用GET服务,在request body偷偷藏了数据,不同服务器的处理方式也是不同的,有些服务器会帮你卸货,读出数据,有些服务器直接忽略,所以,虽然GET可以带request body,也不能保证一定能被接收到。
总结:HTTP只是个行为准则,HTTP的底层是TCP/IP,所以可以理解为GET和POST的底层也是TCP/IP,也就是说,GET/POST都是TCP链接。GET和POST能做的事情从本质上说是一样的。
传输数据方式存在区别:
传送方式:get通过地址栏传输,post通过报文传输(request body)。
get方式的安全性较Post方式要差些,包含机密信息的话,建议用Post数据提交方式,在做数据查询时,建议用Get方式;而在做数据添加、修改或删除时,建议用Post方式。
传送长度:get有长度限制,一般限制在 2kb 左右;post传送的数据量较大,一般被默认为不受限制。 get和post的传送数据大小跟各个浏览器、操作系统以及服务器的限制有关。
因为GET是通过URL提交数据,那么GET可提交的数据量就跟URL的长度有直接关系 了。而实际上,URL不存在参数上限的问题,HTTP协议规范没有对URL长度进行限制。这个限制是特定的浏览器及服务器对它的限制。IE对URL长度的限制是2083字节(2KB+35)。用apache测试,使用get方式,url最长可达8167b。
get请求的过程:
(1)浏览器请求tcp连接(第一次握手)
(2)服务器答应进行tcp连接(第二次握手)
(3)浏览器确认,并发送get请求头和数据(第三次握手,这个报文比较小,所以http会在此时进行第一次数据发送)
(4)服务器返回200 OK响应
而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
post请求的过程:
(1)浏览器请求tcp连接(第一次握手)
(2)服务器答应进行tcp连接(第二次握手)
(3)浏览器确认,并发送post请求头(第三次握手,这个报文比较小,所以http会在此时进行第一次数据发送)
(4)服务器返回100 Continue响应
(5)浏览器发送数据
(6)服务器返回200 OK响应
服务器处理请求:
- 服务器接收到HTTP请求后,会根据请求的内容进行处理。这可能包括查询数据库、读取文件、执行程序等。
- 服务器处理完请求后,生成一个HTTP响应,包括响应行(如状态码)、响应头部和响应正文(所请求的资源)。
Session、Cookie和Token:
HTTP协议本身是无状态的。什么是无状态呢,即服务器无法判断用户身份。
什么是cookie
cookie是由Web服务器保存在用户浏览器上的小文件(key-value格式),包含用户相关的信息。客户端向服务器发起请求,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户身份。
什么是session
session是依赖Cookie实现的。session是服务器端对象
session 是浏览器和服务器会话过程中,服务器分配的一块储存空间。服务器默认为浏览器在cookie中设置 sessionid,浏览器在向服务器请求过程中传输 cookie 包含 sessionid ,服务器根据 sessionid 获取出会话中存储的信息,然后确定会话的身份信息。
cookie与session区别
存储位置与安全性:cookie数据存放在客户端上,安全性较差,session数据放在服务器上,安全性相对更高;
存储空间:单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie,session无此限制
占用服务器资源:session一定时间内保存在服务器上,当访问增多,占用服务器性能,考虑到服务器性能方面,应当使用cookie。
什么是Token
Token的引入:Token是在客户端频繁向服务端请求数据,服务端频繁的去数据库查询用户名和密码并进行对比,判断用户名和密码正确与否,并作出相应提示,在这样的背景下,Token便应运而生。
Token的定义:Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。
使用Token的目的:Token的目的是为了减轻服务器的压力,减少频繁的查询数据库,使服务器更加健壮。
Token 是在服务端产生的。如果前端使用用户名/密码向服务端请求认证,服务端认证成功,那么在服务端会返回 Token 给前端。前端可以在每次请求的时候带上 Token 证明自己的合法地位
session与token区别
session机制存在服务器压力增大,CSRF跨站伪造请求攻击,扩展性不强等问题;
session存储在服务器端,token存储在客户端
token提供认证和授权功能,作为身份认证,token安全性比session好;
session这种会话存储方式方式只适用于客户端代码和服务端代码运行在同一台服务器上,token适用于项目级的前后端分离(前后端代码运行在不同的服务器下)。
浏览器解析服务器的HTTP相应:
-
渲染页面:
a. 浏览器开始解析HTML响应内容,逐步构建DOM树(文档对象模型)。当解析到外部资源(如CSS和JavaScript)时,浏览器会发送额外的HTTP请求去获取这些资源。
b. 浏览器使用CSS解析器对页面进行样式计算,并生成渲染树。
c. 浏览器进行布局和绘制过程,将页面元素摆放在正确的位置,并根据样式信息绘制页面。 -
显示页面:
a. 浏览器将绘制好的页面内容显示在浏览器窗口中,用户可以看到页面并与页面进行交互。
HTTP/1.0和HTTP/2.0在用户主机与服务器建立连接方面有以下差异:
- 连接复用(Multiplexing):HTTP/1.0是无状态的,使用简单的请求-响应模式,每个请求需要创建一个新的连接,在响应完成后会自动断开TCP连接,导致大量延迟。而HTTP2.0使用多路复用技术,可以在单个TCP连接上同时发送多个请求和响应,减少了连接建立的开销。 1.0采用的是单向请求-响应模式,即每个请求只能对应一个响应,请求和响应是一一对应的关系。2.0引入了Server Push机制,服务器可以在客户端请求之前主动推送相关资源,避免了客户端重复请求的等待时间,提高了页面加载速度。
- 头部压缩(Header Compression):HTTP/1.0中的头部信息没有压缩,每次请求都会重复发送头部信息,增加了数据传输的开销。而HTTP/2.0使用HPACK压缩算法对头部信息进行了压缩,减少了数据传输的大小。
- 优先级和流控制(Request Prioritization):HTTP/2.0引入了流的概念,可以将请求和响应切分成多个流进行处理,每个流都可以设置优先级和流控制。这样可以保证重要的请求优先处理,提高了页面加载的速度和性能。
- 服务器推送(Server Push):http/1.0 中,客户端需要明确请求服务器才能获取资源。,而HTTP/2.0支持服务器主动推送资源,服务器可以在客户端请求之前主动推送资源到客户端缓存,提高页面加载速度。
- 二进制分帧(Binary framing):HTTP/1.0使用文本协议,而HTTP/2.0使用二进制协议进行传输。二进制协议更加高效,解析速度更快,并且可以采用二进制压缩和加密算法。
在整个过程中,还包括了一些优化措施,如缓存机制(浏览器会缓存静态资源,如图片、CSS和JavaScript),以及一些安全机制(如HTTPS的加密通信)。。每个步骤都有其特定的协议和规范,以保证数据的传输和交互的可靠性、安全性和效率。
不准确的地方恳请指正~