阅读 1103

面试官最喜欢问☞HTTP及浏览器专题

这是我参与8月更文挑战的第10天,活动详情查看:8月更文挑战

最后更新于 2021年08月17日 23:09

本专题按照以下几个方便进行整理:

  • HTTP
  • 浏览器

适合针对HTTP部分进行全面复习的同学,查缺补漏,知识面比较全,复习完成后,再按照本人整理的面试高频题配合复习,使得找工作事半功倍,一定要理解,不要死记硬背,对于一些概念性的和原理的内容要深入理解。

“你从头读,尽量往下读,直到你一窍不通时,再从头开始,这样坚持往下读,直到你完全读懂为止。”

HTTP

HTTP协议与数据请求

1. HTTP 的基本概念

http: 是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准(TCP),用于从 WWW 服务器传输超文本到本地浏览器的超文本传输协议

2. HTTP工作原理

HTTP协议定义Web客户端如何从Web服务器请求Web页面,以及服务器如何把Web页面传送给客户端。客户端向服务器发送一个请求报文,服务器以一个状态行作为响应。

3. HTTP请求/响应的步骤

  • 1.客户端连接到Web服务器
  • 2.发送HTTP请求
  • 3.服务器接受请求并返回HTTP响应
  • 4.释放连接TCP连接
  • 5.客户端(浏览器)解析HTML内容

记忆口诀:连接发送加响应,释放解析整过程。

4. HTTP报文的组成成分

请求报文{ 请求行、请求头、空行、请求体 } 请求行:{http方法、页面地址、http协议、http版本} 响应报文{ 状态行、响应头、空行、响应体 }

Request Header:

  1. GET /sample.Jsp HTTP/1.1  //请求行
  2. Host:  www.uuid.online/ //请求的目标域名和端口号
  3. Origin: http://localhost:8081/ //请求的来源域名和端口号 (跨域请求时,浏览器会自动带上这个头信息)
  4. Referer: https://localhost:8081/link?query=xxxxx //请求资源的完整URI
  5. User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36 //浏览器信息
  6. Cookie:  BAIDUID=FA89F036:FG=1; BD_HOME=1; sugstore=0  //当前域名下的Cookie
  7. Accept: text/html,image/apng  //代表客户端希望接受的数据类型是html或者是png图片类型 
  8. Accept-Encoding: gzip, deflate  //代表客户端能支持gzip和deflate格式的压缩
  9. Accept-Language: zh-CN,zh;q=0.9  //代表客户端可以支持语言zh-CN或者zh(值得一提的是q(0~1)是优先级权重的意思,不写默认为1,这里zh-CN是1,zh是0.9)
  10. Connection: keep-alive  //告诉服务器,客户端需要的tcp连接是一个长连接

Response Header:

  1. HTTP/1.1 200 OK  // 响应状态行
  2. Date:  Mon, 30 Jul 2018 02:50:55 GMT  //服务端发送资源时的服务器时间
  3. Expires:  Wed, 31 Dec 1969 23:59:59 GMT //比较过时的一种验证缓存的方式,与浏览器(客户端)的时间比较,超过这个时间就不用缓存(不和服务器进行验证),适合版本比较稳定的网页
  4. Cache-Control:  no-cache  // 现在最多使用的控制缓存的方式,会和服务器进行缓存验证,具体见博文”Cache-Control“
  5. etag:  "fb8ba2f80b1d324bb997cbe188f28187-ssl-df"  // 一般是Nginx静态服务器发来的静态文件签名,浏览在没有“Disabled cache”情况下,接收到etag后,同一个url第二次请求就会自动带上“If-None-Match”
  6. Last-Modified:  Fri, 27 Jul 2018 11:04:55 GMT //是服务器发来的当前资源最后一次修改的时间,下次请求时,如果服务器上当前资源的修改时间大于这个时间,就返回新的资源内容
  7. Content-Type:  text/html; charset=utf-8  //如果返回是流式的数据,我们就必须告诉浏览器这个头,不然浏览器会下载这个页面,同时告诉浏览器是utf8编码,否则可能出现乱码
  8. Content-Encoding:  gzip  //告诉客户端,应该采用gzip对资源进行解码
  9. Connection:  keep-alive  //告诉客户端服务器的tcp连接也是一个长连接

5.HTTP 的 5 种方法

  • GET---获取资源
  • POST---传输资源
  • PUT---更新资源
  • DELETE---删除资源
  • HEAD---获取报文首部

6.TCP三次握手

  1. 第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。

  2. 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;

  3. 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。

握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。

7.TCP 四次挥手

1)客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。

2)服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。

3)客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。

4)服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。

5)客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2∗∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。

6)服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。

HTTP 和 HTTPS

1.https 的基本概念

https:是以安全为目标的 HTTP 通道,即 HTTP 下加入 SSL 层进行加密。 主要作用是建立一个信息安全通道,来确保数据的传输,确保网站的真实性。

2.http 和 https 的区别?

  • http 是超文本传输协议,信息是明文传输,https 则是具有安全性的 ssl 加密传输协议。
  • Https 协议需要 ca 证书,费用较高。
  • 使用不同的链接方式,端口也不同,一般,http 协议的端口为 80,https 的端口为 443。
  • http 的连接很简单,是无状态的。

记忆口诀:明文传输超文本,安全等级各不同。CA证书费用高,无状连接端难同。

3.https 协议的工作原理

客户端在使用 HTTPS 方式与 Web 服务器通信时有以下几个步骤:

  1. 客户端使用 https url 访问服务器,则要求 web 服务器建立 ssl 链接
  2. web 服务器接收到客户端的请求之后,会将网站的证书(证书中包含了公钥),返回或 者说传输给客户端
  3. 客户端和 web 服务器端开始协商 SSL 链接的安全等级,也就是加密等级。
  4. 客户端浏览器通过双方协商一致的安全等级,建立会话密钥,然后通过网站的公钥来加密会话密钥,并传送给网站。
  5. web 服务器通过自己的私钥解密出会话密钥
  6. web 服务器通过会话密钥加密与客户端之间的通信

记忆口诀:一连二传三协商,四建五得六使用。

4.https 协议的优点

  • 使用 HTTPS 协议可认证用户和服务器,确保数据发送到正确的客户机和服务器;

  • HTTPS 协议要比 http 协议安全,可防止数据在传输过程中不被窃取、改变,确保数据的完整性。HTTPS 是现行架构下最安全的解决方案,虽然不是绝对安全,但它大幅增加了中间人攻击的成本。

5.https 协议的缺点

  • https 握手阶段比较费时,会使页面加载时间延长 50%,增加 10%~20%的耗电。
  • https 缓存不如 http 高效,会增加数据开销。
  • SSL 证书也需要钱,功能越强大的证书费用越高。
  • SSL 证书需要绑定 IP,不能再同一个 ip 上绑定多个域名,ipv4 资源支持不了这种消耗。

记忆口诀:只因安全可认证,费时费钱费IP,缓存大不如从前,徒增开销也得用。

非对称加密RSA

简介: 

  1. 对称加密算法又称现代加密算法。 
  2. 非对称加密是计算机通信安全的基石,保证了加密数据不会被破解。 
  3. 非对称加密算法需要两个密钥:公开密钥(publickey) 和私有密(privatekey) 
  4. 公开密钥和私有密钥是一对

如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密。  如果用私有密钥对数据进行加密,只有用对应的公开密钥才能解密。

特点:  算法强度复杂,安全性依赖于算法与密钥。  加密解密速度慢。

与对称加密算法的对比:  对称加密只有一种密钥,并且是非公开的,如果要解密就得让对方知道密钥。  非对称加密有两种密钥,其中一个是公开的。

RSA应用场景:  由于RSA算法的加密解密速度要比对称算法速度慢很多,在实际应用中,通常采取  数据本身的加密和解密使用对称加密算法(AES)。 用RSA算法加密并传输对称算法所需的密钥。

TCP和UDP的区别

  1. TCP是面向链接的,而UDP是面向无连接的。

  2. TCP仅支持单播传输,UDP 提供了单播,多播,广播的功能。

  3. TCP的三次握手保证了连接的可靠性; UDP是无连接的、不可靠的一种数据传输协议,首先不可靠性体现在无连接上,通信都不需要建立连接,对接收到的数据也不发送确认信号,发送端不知道数据是否会正确接收。

  4. UDP的头部开销比TCP的更小,数据传输速率更高实时性更好

记忆口诀:无连接多广播,开销小不靠谱。(解释:记住UDP的特点之后相反的就是TCP的特点了,也就知道二者的区别了)

粘包问题分析与对策

TCP粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。

粘包出现原因

简单得说,在流传输中出现,UDP不会出现粘包,因为它有消息边界(参考Windows网络编程)

  1. 发送端需要等缓冲区满才发送出去,造成粘包

    发送方引起的粘包是由TCP协议本身造成的,TCP为提高传输效率,发送方往往要收集到足够多的数据后才发送一包数据。若连续几次发送的数据都很少,通常TCP会根据优化算法把这些数据合成一包后一次发送出去,这样接收方就收到了粘包数据。

  2. 接收方不及时接收缓冲区的包,造成多个包接收

    接收方引起的粘包是由于接收方用户进程不及时接收数据,从而导致粘包现象。这是因为接收方先把收到的数据放在系统接收缓冲区,用户进程从该缓冲区取数据,若下一包数据到达时前一包数据尚未被用户进程取走,则下一包数据放到系统接收缓冲区时就接到前一包数据之后,而用户进程根据预先设定的缓冲区大小从系统接收缓冲区取数据,这样就一次取到了多包数据。

粘包情况有两种,一种是粘在一起的包都是完整的数据包,另一种情况是粘在一起的包有不完整的包

不是所有的粘包现象都需要处理,若传输的数据为不带结构的连续流数据(如文件传输),则不必把粘连的包分开(简称分包)。但在实际工程应用中,传输的数据一般为带结构的数据,这时就需要做分包处理。

在处理定长结构数据的粘包问题时,分包算法比较简单;在处理不定长结构数据的粘包问题时,分包算法就比较复杂。特别是粘在一起的包有不完整的包的粘包情况,由于一包数据内容被分在了两个连续的接收包中,处理起来难度较大。实际工程应用中应尽量避免出现粘包现象。

为了避免粘包现象,可采取以下几种措施:

(1)对于发送方引起的粘包现象,用户可通过编程设置来避免,TCP提供了强制数据立即传送的操作指令push,TCP软件收到该操作指令后,就立即将本段数据发送出去,而不必等待发送缓冲区满;

(2)对于接收方引起的粘包,则可通过优化程序设计、精简接收进程工作量、提高接收进程优先级等措施,使其及时接收数据,从而尽量避免出现粘包现象;

(3)由接收方控制,将一包数据按结构字段,人为控制分多次接收,然后合并,通过这种手段来避免粘包。分包多发

以上提到的三种措施,都有其不足之处。

(1)第一种编程设置方法虽然可以避免发送方引起的粘包,但它关闭了优化算法,降低了网络发送效率,影响应用程序的性能,一般不建议使用。

(2)第二种方法只能减少出现粘包的可能性,但并不能完全避免粘包,当发送频率较高时,或由于网络突发可能使某个时间段数据包到达接收方较快,接收方还是有可能来不及接收,从而导致粘包。

(3)第三种方法虽然避免了粘包,但应用程序的效率较低,对实时应用的场合不适合。

一种比较周全的对策是:接收方创建一预处理线程,对接收到的数据包进行预处理,将粘连的包分开。实验证明这种方法是高效可行的。

HTTP1、HTTP2、HTTP3

HTTP/2 相比于 HTTP/1.1,可以说是大幅度提高了网页的性能,只需要升级到该协议就可以减少很多之前需要做的性能优化工作,虽如此但HTTP/2并非完美的,HTTP/3 就是为了解决 HTTP/2 所存在的一些问题而被推出来的。

HTTP1.1 的缺陷

  1. 高延迟 — 队头阻塞(Head-Of-Line Blocking)

    队头阻塞是指当顺序发送的请求序列中的一个请求因为某种原因被阻塞时,在后面排队的所有请求也一并被阻塞,会导致客户端迟迟收不到数据。

    针对队头阻塞的解决办法:

    • 将同一页面的资源分散到不同域名下,提升连接上限。 
    • 合并小文件减少资源数,使用精灵图。
    • 内联(Inlining)资源是另外一种防止发送很多小图请求的技巧,将图片的原始数据嵌入在CSS文件里面的URL里,减少网络请求次数。
    • 减少请求数量,合并文件。
  2. 无状态特性 — 阻碍交互

    无状态是指协议对于连接状态没有记忆能力。纯净的 HTTP 是没有 cookie 等机制的,每一个连接都是一个新的连接。

    Header里携带的内容过大,在一定程度上增加了传输的成本。且请求响应报文里有大量字段值都是重复的。

  3. 明文传输 — 不安全性

    HTTP/1.1在传输数据时,所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份,无法保证数据的安全性。

  4. 不支持服务端推送

记忆口诀:队头阻塞高延迟,无状态阻交互,明文传输不安全,服务推送不支持。

SPDY 协议与 HTTP/2 简介

1、HTTP/2 简介

HTTP/2是现行HTTP协议(HTTP/1.x)的替代,但它不是重写。HTTP/2基于SPDY,专注于性能,最大的一个目标是在用户和网站间只用一个连接(connection)

2、HTTP/2 新特性

1、二进制传输

HTTP/2传输数据量的大幅减少,主要有两个原因:以二进制方式传输和Header 压缩。我们先来介绍二进制传输,HTTP/2 采用二进制格式传输数据,而非HTTP/1.x 里纯文本形式的报文 ,二进制协议解析起来更高效。HTTP/2 将请求和响应数据分割为更小的帧,并且它们采用二进制编码

2、Header 压缩

HTTP/2并没有使用传统的压缩算法,而是开发了专门的"HPACK”算法,在客户端和服务器两端建立“字典”,用索引号表示重复的字符串,还采用哈夫曼编码来压缩整数和字符串,可以达到50%~90%的高压缩率。

3、多路复用

在 HTTP/2 中引入了多路复用的技术。多路复用很好的解决了浏览器限制同一个域名下的请求数量的问题,同时也更容易实现全速传输。

4、Server Push

HTTP2还在一定程度上改变了传统的“请求-应答”工作模式,服务器不再是完全被动地响应请求,也可以新建“流”主动向客户端发送消息。减少等待的延迟,这被称为"服务器推送"( Server Push,也叫 Cache push)

5、提高安全性

出于兼容的考虑,HTTP/2延续了HTTP/1的“明文”特点,可以像以前一样使用明文传输数据,不强制使用加密通信,不过格式还是二进制,只是不需要解密。

但由于HTTPS已经是大势所趋,而且主流的浏览器Chrome、Firefox等都公开宣布只支持加密的HTTP/2,所以“事实上”的HTTP/2是加密的。也就是说,互联网上通常所能见到的HTTP/2都是使用"https”协议名,跑在TLS上面。HTTP/2协议定义了两个字符串标识符:“h2"表示加密的HTTP/2,“h2c”表示明文的HTTP/2。

HTTP/2 的缺点

虽然 HTTP/2 解决了很多之前旧版本的问题,但它还是存在一个巨大的问题,主要是底层支撑的 TCP 协议造成的。HTTP/2的缺点主要有以下几点:

  1. TCP 以及 TCP+TLS 建立连接时延时
  2. TCP 的队头阻塞并没有彻底解决
  3. 多路复用导致服务器压力上升
  4. 多路复用容易 Timeout

HTTP/3 新特性

1、HTTP/3简介

Google 在推SPDY的时候就搞了个基于 UDP 协议的“QUIC”协议,让HTTP跑在QUIC上而不是TCP上。而“HTTP over QUIC”就是HTTP/3,真正“完美”地解决了“队头阻塞”问题。

QUIC 虽然基于 UDP,但是在原本的基础上新增了很多功能,接下来我们重点介绍几个QUIC新功能。

2、QUIC新功能

QUIC基于UDP,而UDP是“无连接”的,根本就不需要“握手”和“挥手”,所以就比TCP来得快。此外QUIC也实现了可靠传输,保证数据一定能够抵达目的地。它还引入了类似HTTP/2的“流”和“多路复用”,单个“流"是有序的,可能会因为丢包而阻塞,但其他“流”不会受到影响。具体来说QUIC协议有以下特点:

  • 实现了类似TCP的流量控制、传输可靠性的功能

    虽然UDP不提供可靠性的传输,但QUIC在UDP的基础之上增加了一层来保证数据可靠性传输。它提供了数据包重传、拥塞控制以及其他一些TCP中存在的特性。

  • 实现了快速握手功能

    由于QUIC是基于UDP的,所以QUIC可以实现使用0-RTT或者1-RTT来建立连接,这意味着QUIC可以用最快的速度来发送和接收数据,这样可以大大提升首次打开页面的速度。0RTT 建连可以说是 QUIC 相比 HTTP2 最大的性能优势

  • 集成了TLS加密功能

  • 多路复用,彻底解决TCP中队头阻塞的问题

    和TCP不同,QUIC实现了在同一物理连接上可以有多个独立的逻辑数据流。实现了数据流的单独传输,就解决了TCP中队头阻塞的问题。

  • 连接迁移

    TCP 是按照 4 要素(客户端 IP、端口, 服务器 IP、端口)确定一个连接的。而 QUIC 则是让客户端生成一个 Connection ID (64 位)来区别不同连接。只要 Connection ID 不变,连接就不需要重新建立,即便是客户端的网络发生变化。由于迁移客户端继续使用相同的会话密钥来加密和解密数据包,QUIC 还提供了迁移客户端的自动加密验证。

总结

  • HTTP/1.1有两个主要的缺点:安全不足和性能不高。
  • HTTP/2完全兼容HTTP/1,是“更安全的HTTP、更快的HTTPS",二进制传输、头部压缩、多路复用、服务器推送等技术可以充分利用带宽,降低延迟,从而大幅度提高上网体验;
  • QUIC 基于 UDP 实现,是 HTTP/3 中的底层支撑协议,该协议基于 UDP,又取了 TCP 中的精华,实现了即快又可靠的协议。

浏览器

从输入URL到页面加载的全过程

从输入URL到页面加载的主干流程

  1. 首先在浏览器中输入URL

  2. 查找缓存:浏览器先查看浏览器缓存-系统缓存-路由缓存中是否有该地址页面,如果有则显示页面内容。如果没有则进行下一步。

    • 浏览器缓存:浏览器会记录DNS一段时间,因此,只是第一个地方解析DNS请求;
    • 操作系统缓存:如果在浏览器缓存中不包含这个记录,则会使系统调用操作系统, 获取操作系统的记录(保存最近的DNS查询缓存);
    • 路由器缓存:如果上述两个步骤均不能成功获取DNS记录,继续搜索路由器缓存;
    • ISP缓存:若上述均失败,继续向ISP搜索。
  3. DNS域名解析:浏览器向DNS服务器发起请求,解析该URL中的域名对应的IP地址。DNS服务器是基于UDP的,因此会用到UDP协议。

  4. 建立TCP连接:解析出IP地址后,根据IP地址和默认80端口,和服务器建立TCP连接

  5. 发起HTTP请求:浏览器发起读取文件的HTTP请求,,该请求报文作为TCP三次握手的第三次数据发送给服务器

  6. 服务器响应请求并返回结果:服务器对浏览器请求做出响应,并把对应的html文件发送给浏览器

  7. 关闭TCP连接:通过四次挥手释放TCP连接

  8. 浏览器渲染:客户端(浏览器)解析HTML内容并渲染出来,浏览器接收到数据包后的解析流程为:

    • 构建DOM树:词法分析然后解析成DOM树(dom tree),是由dom元素及属性节点组成,树的根是document对象
    • 构建CSS规则树:生成CSS规则树(CSS Rule Tree)
    • 构建render树:Web浏览器将DOM和CSSOM结合,并构建出渲染树(render tree)
    • 布局(Layout):计算出每个节点在屏幕中的位置
    • 绘制(Painting):即遍历render树,并使用UI后端层绘制每个节点。

    浏览器渲染流程图

  9. JS引擎解析过程:调用JS引擎执行JS代码(JS的解释阶段,预处理阶段,执行阶段生成执行上下文,VO,作用域链、回收机制等等)

    • 创建window对象:window对象也叫全局执行环境,当页面产生时就被创建,所有的全局变量和函数都属于window的属性和方法,而DOM Tree也会映射在window的doucment对象上。当关闭网页或者关闭浏览器时,全局执行环境会被销毁。

    • 加载文件:完成js引擎分析它的语法与词法是否合法,如果合法进入预编译

    • 预编译:在预编译的过程中,浏览器会寻找全局变量声明,把它作为window的属性加入到window对象中,并给变量赋值为'undefined';寻找全局函数声明,把它作为window的方法加入到window对象中,并将函数体赋值给他(匿名函数是不参与预编译的,因为它是变量)。而变量提升作为不合理的地方在ES6中已经解决了,函数提升还存在。

    • 解释执行:执行到变量就赋值,如果变量没有被定义,也就没有被预编译直接赋值,在ES5非严格模式下这个变量会成为window的一个属性,也就是成为全局变量。string、int这样的值就是直接把值放在变量的存储空间里,object对象就是把指针指向变量的存储空间。函数执行,就将函数的环境推入一个环境的栈中,执行完成后再弹出,控制权交还给之前的环境。JS作用域其实就是这样的执行流机制实现的。

//从浏览器输入一个url到页面渲染完成,发生了什么?
1.DNS解析 将域名解析为IP地址 如果是IP地址则跳过
    - 先读取浏览器DNS的缓存
    - 如果没有则查找系统DNS缓存
    - 如果还没有 则去路由DNS缓存中查找
    - 如果还没有则去网络运营商DNS缓存中查找
    - 再找不到 则会递归搜索,如 blog.baidu.com
        - 先在.com域名下查找DNS解析
        - 找不到再在.baidu域名下查找DNS解析
        - 找不到再在.blog域名下查找DNS解析
        -依然找不到则报错
2.TCP链接 TCP的三次握手
    第一次握手,由浏览器发起,告诉服务器我要发送请求了
    第二次握手,由服务器发起,告诉浏览器我准备接受了,你发送吧
    第三次握手,由浏览器发起,告诉浏览器我能接收到回应,下面就发真正的请求
3.发送请求
    -请求报文,http协议的通信内容
4.接受响应
    -响应报文
5.渲染页面
    -遇见html标签,会调用html解析器解析成Token并构成Dom树,
    -遇见style/link标签,会调用css解析器,处理css标记并构建成cssom树
    -遇见script标签,调用JavaScript解析器,处理script代码(如绑定事件
    -将dom树和cssom树合并成一个渲染树
    -根据渲染树来计算布局,计算每个节点的几何信息(布局)
注意:这五个步骤不一定按照顺序执行,如果dom树和cssom树被修改了,可能会执行多次布局和渲染,往往实际页面中,这些步骤都会执行多次的。
6.断开链接 TCP的四次挥手
    -第一次由客户端发起,发送给服务器,告诉服务器我已经发送完了(请求报文),你准备关闭吧
    -第二次由服务器发起,发给浏览器,告诉浏览器你的请求我收到了(请求报文),我还没准备好,请等待我通知
    -第三次由服务器发起,发给浏览器,告诉浏览器我这边数据发送完了(响应请求),准备关闭链接
    -第四次由客户端发起,发送给服务器,告诉服务器可以断开链接了

假设Client端发起中断连接请求,也就是发送FIN报文。
Server端接到FIN报文后,意思是说"我Client端没有数据要发给你了",但是如果你还有数据没有发送完成,则不必急着关闭Socket,可以继续发送数据。所以你先发送ACK,"告诉Client端,你的请求我收到了,但是我还没准备好,请继续你等我的消息"。这个时候Client端就进入FIN_WAIT状态,继续等待Server端的FIN报文。
当Server端确定数据已发送完成,则向Client端发送FIN报文,"告诉Client端,好了,我这边数据发完了,准备好关闭连接了"。
Client端收到FIN报文后,"就知道可以关闭连接了,但是他还是不相信网络,怕Server端不知道要关闭,所以发送ACK后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。“
Server端收到ACK后,"就知道可以断开连接了"。
Client端等待了2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,我Client端也可以关闭连接了。
Ok,TCP连接就这样关闭了!
复制代码

在浏览器中输入URL到显示页面经历哪些过程,涉及到哪些协议?

浏览器要将URL解析为IP地址,解析域名就要用到DNS协议,首先主机会查询DNS的缓存,如果没有就给本地DNS发送查询请求。DNS查询分为两种方式,一种是递归查询,一种是迭代查询。如果是迭代查询,本地的DNS服务器,向根域名服务器发送查询请求,根域名服务器告知该域名的一级域名服务器,然后本地服务器给该一级域名服务器发送查询请求,然后依次类推直到查询到该域名的IP地址。DNS服务器是基于UDP的,因此会用到UDP协议。

得到IP地址后,浏览器就要与服务器建立一个http连接。因此要用到http协议。http生成一个get请求报文,将该报文传给TCP层处理,所以还会用到TCP协议。如果采用https还会使用https协议先对http数据进行加密。TCP层如果有需要先将HTTP数据包分片,分片依据路径MTU和MSS。TCP的数据包然后会发送给IP层,用到IP协议。IP层通过路由选路,一跳一跳发送到目的地址。当然在一个网段内的寻址是通过以太网协议实现(也可以是其他物理层协议,比如PPP,SLIP),以太网协议需要直到目的IP地址的物理地址,有需要ARP协议。

其中:

1、DNS协议,http协议,https协议属于应用层

应用层是体系结构中的最高层。应用层确定进程之间通信的性质以满足用户的需要。这里的进程就是指正在运行的程序。应用层不仅要提供应用进程所需要的信息交换和远地操作,而且还要作为互相作用的应用进程的用户代理,来完成一些为进行语义上有意义的信息交换所必须的功能。应用层直接为用户的应用进程提供服务。

2、TCP/UDP属于传输层

传输层的任务就是负责主机中两个进程之间的通信。因特网的传输层可使用两种不同协议:即面向连接的传输控制协议TCP,和无连接的用户数据报协议UDP。面向连接的服务能够提供可靠的交付,但无连接服务则不保证提供可靠的交付,它只是“尽最大努力交付”。这两种服务方式都很有用,备有其优缺点。在分组交换网内的各个交换结点机都没有传输层。

3、IP协议,ARP协议属于网络层

网络层负责为分组交换网上的不同主机提供通信。在发送数据时,网络层将运输层产生的报文段或用户数据报封装成分组或包进行传送。在TCP/IP体系中,分组也叫作IP数据报,或简称为数据报。网络层的另一个任务就是要选择合适的路由,使源主机运输层所传下来的分组能够交付到目的主机。

4、数据链路层

当发送数据时,数据链路层的任务是将在网络层交下来的IP数据报组装成帧,在两个相邻结点间的链路上传送以帧为单位的数据。每一帧包括数据和必要的控制信息(如同步信息、地址信息、差错控制、以及流量控制信息等)。控制信息使接收端能够知道—个帧从哪个比特开始和到哪个比特结束。控制信息还使接收端能够检测到所收到的帧中有无差错。

5、物理层

物理层的任务就是透明地传送比特流。在物理层上所传数据的单位是比特。传递信息所利用的一些物理媒体,如双绞线、同轴电缆、光缆等,并不在物理层之内而是在物理层的下面。因此也有人把物理媒体当做第0层。

浏览器的主要功能

浏览器的主要功能就是向服务器发出请求,在浏览器窗口中展示您选择的网络资源。这里所说的资源一般是指 HTML 文档,也可以是 PDF、图片或其他的类型。资源的位置由用户使用 URI(统一资源标示符)指定。

浏览器的工作原理

渲染引擎一开始会从网络层获取请求文档的内容,内容的大小一般限制在 8000 个块以内。

然后进行如下所示的基本流程:

图:渲染引擎的基本流程。

渲染引擎将开始解析 HTML 文档,并将各标记逐个转化成“内容树”上的 DOM 节点。同时也会解析外部 CSS 文件以及样式元素中的样式数据。HTML 中这些带有视觉指令的样式信息将用于创建另一个树结构:渲染树

渲染树包含多个带有视觉属性(如颜色和尺寸)的矩形。这些矩形的排列顺序就是它们将在屏幕上显示的顺序。

渲染树构建完毕之后,进入“布局”处理阶段,也就是为每个节点分配一个应出现在屏幕上的确切坐标。下一个阶段是绘制 - 渲染引擎会遍历渲染树,由用户界面后端层将每个节点绘制出来。

需要着重指出的是,这是一个渐进的过程。为达到更好的用户体验,渲染引擎会力求尽快将内容显示在屏幕上。它不必等到整个 HTML 文档解析完毕之后,就会开始构建呈现树和设置布局。在不断接收和处理来自网络的其余内容的同时,渲染引擎会将部分内容解析并显示出来。

浏览器的主要组成部分是什么?

  1. 用户界面 - 包括地址栏、前进/后退按钮、书签菜单等。除了浏览器主窗口显示的您请求的页面外,其他显示的各个部分都属于用户界面。
  2. 浏览器引擎 - 在用户界面和呈现引擎之间传送指令。
  3. 呈现引擎 - 负责显示请求的内容。如果请求的内容是 HTML,它就负责解析 HTML 和 CSS 内容,并将解析后的内容显示在屏幕上。
  4. 网络 - 用于网络调用,比如 HTTP 请求。其接口与平台无关,并为所有平台提供底层实现。
  5. 用户界面后端 - 用于绘制基本的窗口小部件,比如组合框和窗口。其公开了与平台无关的通用接口,而在底层使用操作系统的用户界面方法。
  6. JavaScript 解释器。用于解析和执行 JavaScript 代码。
  7. 数据存储。这是持久层。浏览器需要在硬盘上保存各种数据,例如 Cookie。新的 HTML 规范 (HTML5) 定义了“网络数据库”,这是一个完整(但是轻便)的浏览器内数据库。

图:浏览器的主要组件。

值得注意的是,和大多数浏览器不同,Chrome 浏览器的每个标签页都分别对应一个呈现引擎实例。每个标签页都是一个独立的进程。

浏览器是如何渲染UI的?

  1. 浏览器获取HTML文件,然后对文件进行解析,形成DOM Tree
  2. 与此同时,进行CSS解析,生成Style Rules
  3. 接着将DOM Tree与Style Rules合成为 Render Tree
  4. 接着进入布局(Layout)阶段,也就是为每个节点分配一个应出现在屏幕上的确切坐标
  5. 随后调用GPU进行绘制(Paint),遍历Render Tree的节点,并将元素呈现出来

image.png

DOM Tree是如何构建的?

  1. 转码: 浏览器将接收到的二进制数据按照指定编码格式转化为HTML字符串
  2. 生成Tokens: 之后开始parser,浏览器会将HTML字符串解析成Tokens
  3. 构建Nodes: 对Node添加特定的属性,通过指针确定 Node 的父、子、兄弟关系和所属 treeScope
  4. 生成DOM Tree: 通过node包含的指针确定的关系构建出DOM
    Tree

2019-06-22-11-48-00

浏览器重绘与重排的区别?

  • 重排/回流(Reflow):当DOM的变化影响了元素的几何信息,浏览器需要重新计算元素的几何属性,将其安放在界面中的正确位置,这个过程叫做重排。表现为重新生成布局,重新排列元素。
  • 重绘(Repaint): 当一个元素的外观发生改变,但没有改变布局,重新把元素外观绘制出来的过程,叫做重绘。表现为某些元素的外观被改变

单单改变元素的外观,肯定不会引起网页重新生成布局,但当浏览器完成重排之后,将会重新绘制受到此次重排影响的部分

重排和重绘代价是高昂的,它们会破坏用户体验,并且让UI展示非常迟缓,而相比之下重排的性能影响更大,在两者无法避免的情况下,一般我们宁可选择代价更小的重绘。

『重绘』不一定会出现『重排』,『重排』必然会出现『重绘』。

如何触发重排和重绘?

任何改变用来构建渲染树的信息都会导致一次重排或重绘:

  • 添加、删除、更新DOM节点
  • 通过display: none隐藏一个DOM节点-触发重排和重绘
  • 通过visibility: hidden隐藏一个DOM节点-只触发重绘,因为没有几何变化
  • 移动或者给页面中的DOM节点添加动画
  • 添加一个样式表,调整样式属性
  • 用户行为,例如调整窗口大小,改变字号,或者滚动。

如何避免重绘或者重排?

  1. 集中改变样式,不要一条一条地修改 DOM 的样式。

  2. 不要把 DOM 结点的属性值放在循环里当成循环里的变量。

  3. 为动画的 HTML 元件使用 fixedabsoultposition,那么修改他们的 CSS 是不会 reflow 的。

  4. 不使用 table 布局。因为可能很小的一个小改动会造成整个 table 的重新布局。

  5. 尽量只修改position:absolutefixed元素,对其他元素影响不大

  6. 动画开始GPU加速,translate使用3D变化

  7. 提升为合成层

    将元素提升为合成层有以下优点:

    • 合成层的位图,会交由 GPU 合成,比 CPU 处理要快
    • 当需要 repaint 时,只需要 repaint 本身,不会影响到其他的层
    • 对于 transform 和 opacity 效果,不会触发 layout 和 paint

    提升合成层的最好方式是使用 CSS 的 will-change 属性:

    #target {
      will-change: transform;
    }
    复制代码

    关于合成层的详解请移步无线性能优化:Composite

利用Socket建立网络连接的步骤

建立Socket连接至少需要一对套接字,其中一个运行于客户端,称为ClientSocket ,另一个运行于服务器端,称为ServerSocket 。

套接字之间的连接过程分为三个步骤:服务器监听,客户端请求,连接确认。

  1、服务器监听:服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态,等待客户端的连接请求。

  2、客户端请求:指客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。

  为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。

  3、连接确认:当服务器端套接字监听到或者说接收到客户端套接字的连接请求时,就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,双方就正式建立连接。

而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。

GET与POST的区别

1.浏览器回退表现不同 GET在浏览器回退时时无害的,而POST会再次提交请求

2.浏览器对请求地址的处理不同 GET请求地址会被浏览器主动缓存,而POST不会,除非手动设置

3.浏览器对响应的处理不同GET请求参数会被完整的保留在浏览器历史记录里,而POST中的参数不会被保留

4.参数大小不同. GET请求在URL中传送的参数是有长度的限制,而POST没有限制。Http Get方法提交的数据大小长度并没有限制,HTTP协议规范没有对URL长度进行限制。这个限制是特定的浏览器及服务器对它的限制。理论上讲,POST是没有大小限制的。HTTP协议规范也没有进行大小限制,起限制作用的是服务器的处理程序的处理能力。

5.安全性不同. GET参数通过URL传递,会暴露,不安全;POST放在Requset Body中,相对更安全.post也可以将参数放在url上,body类请求兼容url类请求

6.针对数据操作的类型不同.GET对数据进行查询,POST主要对数据进行增删改!简单说,GET是只读,POST是写。

HTTP 请求跨域问题

  1. 跨域的原理

    跨域,是指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的。
    同源策略,是浏览器对 JavaScript 实施的安全限制,只要协议、域名、端口有任何一个不同,都被当作是不同的域。
    跨域原理,即是通过各种方式,避开浏览器的安全限制

  2. 解决方案

    最初做项目的时候,使用的是jsonp,但存在一些问题,使用get请求不安全,携带数据较小,后来也用过iframe,但只有主域相同才行,也是存在些问题,后来通过了解和学习发现使用代理和proxy代理配合起来使用比较方便,就引导后台按这种方式做下服务器配置,在开发中使用proxy,在服务器上使用nginx代理,这样开发过程中彼此都方便,效率也高;现在h5新特性还有 windows.postMessage()

    跨域是个比较古老的命题了,历史上跨域的实现手段有很多,我们现在主要介绍三种比较主流的跨域方案,其余的方案我们就不深入讨论了,因为使用场景很少,也没必要记这么多奇技淫巧。

    • 最经典的跨域方案JSONP

      ajax 请求受同源策略影响,不允许进行跨域请求,而 script 标签 src 属性中的链 接却可以访问跨域的 js 脚本,利用这个特性,服务端不再返回 JSON 格式的数据,而是 返回一段调用某个函数的 js 代码,在 src 中进行了调用,这样实现了跨域。

      步骤:

      1. 去创建一个script标签
      2. script的src属性设置接口地址
      3. 接口参数,必须要带一个自定义函数名,要不然后台无法返回数据
      4. 通过定义函数名去接受返回的数据
      //动态创建 script
      var script = document.createElement('script');
      
      // 设置回调函数
      function getData(data) {
          console.log(data);
      }
      
      //设置 script 的 src 属性,并设置请求地址
      script.src = 'http://localhost:3000/?callback=getData';
      
      // 让 script 生效
      document.body.appendChild(script);
      复制代码

      JSONP 的缺点:
      JSON 只支持 get,因为 script 标签只能使用 get 请求; JSONP 需要后端配合返回指定格式的数据。JSONP存在安全性问题:CSRF攻击、XSS漏洞

    • 最流行的跨域方案 cors

      CORS(Cross-origin resource sharing)跨域资源共享 是一种机制,是目前主流的跨域解决方案,它使用额外的 HTTP 头来告诉浏览器 让运行在一个 origin (domain) 上的Web应用被准许访问来自不同源服务器上的指定的资源。

      1.浏览器端会自动向请求头添加origin字段,表明当前请求来源。
      2.服务器设置Access-Control-Allow-Origin、Access-Control-Allow-Methods、Access-Control-Allow-Headers等 HTTP响应头字段之后,浏览器将会允许跨域请求。

    • 最方便的跨域方案 proxy代理+ Nginx

      nginx是一款极其强大的web服务器,其优点就是轻量级、启动快、高并发。

      现在的新项目中nginx几乎是首选,我们用node或者java开发的服务通常都需要经过nginx的反向代理。

    • document.domain 基础域名相同 子域名不同

    • window.name 利用在一个浏览器窗口内,载入所有的域名都是共享一个window.name

    • window.postMessage() 利用h5新特性window.postMessage()

    • Websocket

客户端与服务端长连接的几种方式

  1. ajax 轮询 实现原理:ajax 轮询指客户端每间隔一段时间向服务端发起请求,保持数据的同步。

    优点:可实现基础(指间隔时间较短)的数据更新。

    缺点:这种方法也只是尽量的模拟即时传输,但并非真正意义上的即时通讯,很有可能出现客户端请求时,服务端数据并未更新。或者服务端数据已更新,但客户端未发起请求。导致多次请求资源浪费,效率低下。【数据更新不及时,效率低下

  2. long poll 长轮询

    实现原理: long poll 指的是客户端发送请求之后,如果没有数据返回,服务端会将请求挂起放入队列(不断开连接)处理其他请求,直到有数据返回给客户端。然后客户端再次发起请求,以此轮询。在 HTTP1.0 中客户端可以设置请求头 Connection:keep-alive,服务端收到该请求头之后知道这是一个长连接,在响应报文头中也添加 Connection:keep-alive。客户端收到之后表示长连接建立完成,可以继续发送其他的请求。在 HTTP1.1 中默认使用了 Connection:keep-alive 长连接。

    优点:减少客户端的请求,降低无效的网络传输,保证每次请求都有数据返回,不会一直占用线程。

    缺点:无法处理高并发,当客户端请求量大,请求频繁时对服务器的处理能力要求较高。服务器一直保持连接会消耗资源,需要同时维护多个线程,服务器所能承载的 TCP 连接数是有上限的,这种轮询很容易把连接数顶满。每次通讯都需要客户端发起,服务端不能主动推送。【无法处理高并发,消耗服务器资源严重,服务端不能主动推送

  3. iframe 长连接

    实现原理:
    在网页上嵌入一个 iframe 标签,该标签的 src 属性指向一个长连接请求。这样服务端就可以源源不断地给客户端传输信息。保障信息实时更新。

    优点:消息及时传输。

    缺点消耗服务器资源

  4. WebSocket

    实现原理: Websocket 实现了客户端与服务端的双向通信,只需要连接一次,就可以相互传输数据,很适合实时通讯、数据实时更新等场景。

    Websocket 协议与 HTTP 协议没有关系,它是一个建立在 TCP 协议上的全新协议,为了兼容 HTTP 握手规范,在握手阶段依然使用 HTTP 协议,握手完成之后,数据通过 TCP 通道进行传输。

    Websoket 数据传输是通过 frame 形式,一个消息可以分成几个片段传输。这样大数据可以分成一些小片段进行传输,不用考虑由于数据量大导致标志位不够的情况。也可以边生成数据边传递消息,提高传输效率。

    优点: 双向通信。客户端和服务端双方都可以主动发起通讯。 没有同源限制。客户端可以与任意服务端通信,不存在跨域问题。 数据量轻。第一次连接时需要携带请求头,后面数据通信都不需要带请求头,减少了请求头的负荷。 传输效率高。因为只需要一次连接,所以数据传输效率高。

    缺点: 长连接需要后端处理业务的代码更稳定,推送消息相对复杂;
    长连接受网络限制比较大,需要处理好重连。
    兼容性,WebSocket 只支持 IE10 及其以上版本。
    服务器长期维护长连接需要一定的成本,各个浏览器支持程度不一;
    成熟的 HTTP 生态下有大量的组件可以复用,WebSocket 则没有,遇到异常问题难以快速定位快速解决。【需要后端代码稳定,受网络限制大,兼容性差,维护成本高,生态圈小】

Cookie、sessionStorage、localStorage 的区别

相同点

  • 存储在客户端

不同点

  • cookie数据大小不能超过4k;sessionStorage和localStorage的存储比cookie大得多,可以达到5M+
  • cookie设置的过期时间之前一直有效;localStorage永久存储,浏览器关闭后数据不丢失除非主动删除数据;sessionStorage数据在当前浏览器窗口关闭后自动删除
  • cookie的数据会自动的传递到服务器;sessionStorage和localStorage数据保存在本地

HTTP状态码及常见状态码

HTTP状态码

  • 1xx:指示信息类,表示请求已接受,继续处理
  • 2xx:指示成功类,表示请求已成功接受
  • 3xx:指示重定向,表示要完成请求必须进行更近一步的操作
  • 4xx:指示客户端错误,请求有语法错误或请求无法实现
  • 5xx:指示服务器错误,服务器未能实现合法的请求

常见状态码

  • 200 OK:客户端请求成功

  • 301 Moved Permanently:所请求的页面已经永久重定向至新的URL

  • 302 Found:所请求的页面已经临时重定向至新的URL

  • 304 Not Modified 未修改。

  • 403 Forbidden:对请求页面的访问被禁止

  • 404 Not Found:请求资源不存在

  • 500 Internal Server Error:服务器发生不可预期的错误原来缓冲的文档还可以继续使用

  • 503 Server Unavailable:请求未完成,服务器临时过载或宕机,一段时间后可恢复正常

  • 1xx(临时响应)表示临时响应并需要请求者继续执行操作的状态码

    • 100 - 继续 请求者应当继续提出请求。服务器返回此代码表示已收到请求的第一部分,正在等待其余部分
    • 101 - 切换协议 请求者已要求服务器切换协议,服务器已确认并准备切换
  • 2xx(成功)表示成功处理了请求的状态码

    • 200 - 成功 服务器已经成功处理了请求。通常,这表示服务器提供了请求的网页
    • 201 - 已创建 请求成功并且服务器创建了新的资源
    • 202 - 已接受 服务器已接受请求,但尚未处理
    • 203 - 非授权信息 服务器已经成功处理了请求,但返回的信息可能来自另一来源
    • 204 - 无内容 服务器成功处理了请求,但没有返回任何内容
    • 205 - 重置内容 服务器成功处理了请求,但没有返回任何内容
  • 3xx(重定向)表示要完成请求,需要进一步操作;通常,这些状态代码用来重定向

    • 300 - 多种选择 针对请求,服务器可执行多种操作。服务器可根据请求者(user agent)选择一项操作,或提供操作列表供请求者选择
    • 301 - 永久移动 请求的网页已永久移动到新位置。服务器返回此响应(对GET或HEAD请求的响应)时,会自动将请求者转到新位置
    • 302 - 临时移动 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求
    • 303 - 查看其它位置 请求者应当对不同的位置使用单独的GET请求来检索响应时,服务器返回此代码
    • 304 - 未修改 自上次请求后,请求的网页未修改过。服务器返回此响应,不会返回网页的内容
    • 305 - 使用代理 请求者只能使用代理访问请求的网页。如果服务器返回此响应,还表示请求者应使用代理
    • 307 - 临时性重定向 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有的位置来进行以后的请求
  • 4xx(请求错误)这些状态码表示请求可能出错,妨碍了服务器的处理

    • 400 - 错误请求 服务器不理解请求的语法
    • 401 - 未授权 请求要求身份验证。对于需要登录的网页,服务器可能返回此响应
    • 403 - 禁止 服务器拒绝请求
    • 404 - 未找到 服务器找不到请求的网页
    • 405 - 方法禁用 禁用请求中指定的方法
    • 406 - 不接受 无法使用请求的内容特性响应请求的网页
    • 407 - 需要代理授权 此状态码与401(未授权)类似,但指定请求者应当授权使用代理
    • 408 - 请求超时 服务器等候请求时发生超时
    • 410 - 已删除 如果请求的资源已永久删除,服务器就会返回此响应
    • 413 - 请求实体过大 服务器无法处理请求,因为请求实体过大,超出了服务器的处理能力
    • 414 - 请求的URI过长 请求的URI(通常为网址)过长,服务器无法处理
  • 5xx(服务器错误)这些状态码表示服务器在尝试处理请求时发生内部错误。这些错误可能是服务器本身的错误,而不是请求出错

    • 500 - 服务器内部错误 服务器遇到错误,无法完成请求
    • 501 - 尚未实施 服务器不具备完成请求的功能。例如,服务器无法识别请求方法时可能会返回此代码
    • 502 - 错误网关 服务器作为网关或代理,从上游服务器无法收到无效响应
    • 503 - 服务器不可用 服务器目前无法使用(由于超载或者停机维护)。通常,这只是暂时状态
    • 504 - 网关超时 服务器作为网关代理,但是没有及时从上游服务器收到请求
    • 505 - HTTP版本不受支持 服务器不支持请求中所用的HTTP协议版本

说一下浏览器的缓存机制呢

浏览器第一次向服务器发起该请求后拿到请求结果,会根据响应报文中HTTP头的缓存标识,决定是否缓存结果,是则将请求结果和缓存标识存入浏览器缓存中。

浏览器缓存分为强制缓存协商缓存,强制缓存优先于协商缓存进行。

强制缓存是我们在第一次请求资源时在 http 响应头设置一个过期时间,在时效内都将直接从浏览器进行获取,常见的 http 响应头字段如 Cache-Control 和 Expires

协商缓存是我们通过 http 响应头字段 etag 或者 Last-Modified 等判断服务器上资源是否修改,如果修改则从服务器重新获取,如果未修改则 304 指向浏览器缓存中进行获取

  • 若强制缓存(Cache-Control 和 Expires,Cache-Control优先级高于Expires)生效则直接使用缓存
  • 若不生效则进行协商缓存(Last-Modified / If-Modified-Since和Etag / If-None-Match,其中Etag / If-None-Match的优先级比Last-Modified / If-Modified-Since高),协商缓存由服务器决定是否使用缓存
  • 若协商缓存失效,那么代表该请求的缓存失效,重新获取请求结果,再存入浏览器缓存中;生效则返回304,继续使用缓存

相关问题:

  • http缓存。Etag和Last-modified比较。

  • etag是怎么判断资源是否更改的:hash算法或者last-modified与content length表示为16进制组合(nginx)

  • etag解决了last-modified什么问题:资源周期性更改,但内容不改变;if-modified-since只能查询到s级别的更改;服务器不能精确得到文件最后的修改时间

  • 哈希函数 md5 sha1

    • md5: 对于原始消息做有损的压缩计算,生成消息摘要;单向不可逆;可用于密码保存

image.png

介绍下304过程

  • a. 浏览器请求资源时首先命中资源的Expires 和 Cache-Control,Expires 受限于本地时间,如果修改了本地时间,可能会造成缓存失效,可以通过Cache-control: max-age指定最大生命周期,状态仍然返回200,但不会请求数据,在浏览器中能明显看到from cache字样。

  • b. 强缓存失效,进入协商缓存阶段,首先验证ETagETag可以保证每一个资源是唯一的,资源变化都会导致ETag变化。服务器根据客户端上送的If-None-Match值来判断是否命中缓存。

  • c. 协商缓存Last-Modify/If-Modify-Since阶段,客户端第一次请求资源时,服务服返回的header中会加上Last-Modify,Last-modify是一个时间标识该资源的最后修改时间。再次请求该资源时,request的请求头中会包含If-Modify-Since,该值为缓存之前返回的Last-Modify。服务器收到If-Modify-Since后,根据资源的最后修改时间判断是否命中缓存。

浏览器样式兼容

一、CSS初始化

每个浏览器的css默认样式不尽相同,所以最简单有效的方式就是对其进行初始化(覆盖默认样式)

常见 :  *{ margin: 0; padding: 0;}

库:normalize.css

二、浏览器私有属性

常用的前缀有:

firefox浏览器 :-moz-

chrome、safari :-webkit-

opera :-o- / -xv-

IE浏览器 :-ms-(目前只有 IE 8+支持)

三、CSS hack(条件hack、属性级hack、选择符级hack)

说下进程、线程和协程

进程是一个具有一定独立功能的程序在一个数据集上的一次动态执行的过程,是操作系统进行资源分配和调度的一个独立单位,是应用程序运行的载体。进程是一种抽象的概念,从来没有统一的标准定义。

线程是程序执行中一个单一的顺序控制流程,是程序执行流的最小单元,是处理器调度和分派的基本单位。一个进程可以有一个或多个线程,各个线程之间共享程序的内存空间(也就是所在进程的内存空间)。一个标准的线程由线程ID、当前指令指针(PC)、寄存器和堆栈组成。而进程由内存空间(代码、数据、进程空间、打开的文件)和一个或多个线程组成。

协程,英文Coroutines,是一种基于线程之上,但又比线程更加轻量级的存在,这种由程序员自己写程序来管理的轻量级线程叫做『用户空间线程』,具有对内核来说不可见的特性。

进程和线程的区别与联系

【区别】:

调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位;

并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可并发执行;

拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源。

系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。但是进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个进程死掉就等于所有的线程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。

【联系】:

一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程;

资源分配给进程,同一进程的所有线程共享该进程的所有资源;

处理机分给线程,即真正在处理机上运行的是线程;

线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。

☞了解更多

进程间的通信方式

进程通信: 每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程A把数据从用户空间拷到内核缓冲区,进程B再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信。

进程间的通信方式:管道、有名管道、信号、消息队列、共享内存、信号量、socket

匿名管道( pipe ): 管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系

高级管道(popen):将另一个程序当做一个新的进程在当前程序进程中启动,则它算是当前程序的子进程,这种方式我们成为高级管道方式。

有名管道 (named pipe) : 有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。

消息队列( message queue ) : 消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。

信号量( semophore ) : 信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。

信号 ( sinal ) : 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。

共享内存( shared memory ) :共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信。

套接字( socket ) 通信: 套接口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同机器间的进程通信

页面渲染优化

基于对渲染过程的了解,推荐一下优化:

  • HTML 文档结构层次尽量少,最好不深于 6 层
  • 脚本尽量放后边,避免组织页面加载
  • 少量首屏样式可以放在便签内
  • 样式结构层次尽量简单
  • 脚本减少 DOM 操作,减少回流,尽量缓存访问 DOM 的样式信息
  • 尽量减少 JS 修改样式,可以通过修改 class 名的方式解决
  • 减少 DOM 查找,缓存 DOM 查找结果
  • 动画在屏幕外或页面滚动时,尽量停止

image.png

理解xss,csrf,ddos攻击原理以及避免方式

XSS(Cross-Site Scripting跨站脚本攻击)是一种代码注入攻击。攻击者在目标网站上注入恶意代码,当被攻击者登陆网站时就会执行这些恶意代码,这些脚本可以读取 cookie,session tokens,或者其它敏感的网站信息,对用户进行钓鱼欺诈,甚至发起蠕虫攻击等。

CSRFCross-site request forgery跨站请求伪造:攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。

XSS避免方式:

  1. url参数使用encodeURIComponent方法转义
  2. 尽量不是有InnerHtml插入HTML内容
  3. 使用特殊符号、标签转义符。

CSRF避免方式:

  1. 添加验证码

  2. 使用token

    • 服务端给用户生成一个token,加密后传递给用户
    • 用户在提交请求时,需要携带这个token
    • 服务端验证token是否正确

DDoS又叫分布式拒绝服务,全称 Distributed Denial of Service,其原理就是利用大量的请求造成资源过载,导致服务不可用。

DDos避免方式:

  1. 限制单IP请求频率。
  2. 防火墙等防护设置禁止ICMP包等
  3. 检查特权端口的开放

360技术:嗨,送你一张Web性能优化地图

相关文档

  1. 解读 HTTP1/HTTP2/HTTP3
  2. 2021年前端面试知识点大厂必备

如果这篇文章帮到了你,记得点赞👍收藏加关注哦😊,希望点赞多多多多...

文中如有错误,欢迎在评论区指正


往期文章

文章分类
前端
文章标签