一、如何解决跨域问题
什么时候需要进行跨域?
跨域(Cross-Origin)指的是在同一页面中,资源所在的域名、协议或端口不同,浏览器为了安全考虑,会限制页面脚本与第三方服务进行交互,这种限制称为同源策略(Same-Origin Policy)。当请求违背了上述的同源策略时,就需要跨域:
下面是一些常见的需要跨域的情况:
- 当前页面通过 Ajax 请求不同域名下的数据接口;
- 页面中嵌入了来自其他域名的资源,如图片、视频、字体等;
- 使用 iframe 引入其他网站的页面或者其他网站使用 iframe 引入本网站的页面;
- 前端应用使用 WebSocket 进行跨域通信等。
1.1 CORS
一般情况下CORS跨域由服务器实现,服务器实现CORS请求就可以跨域通信了。
如果需要带cookie请求,前后端都需要设置。
xhr.withCredentials = true
1.2 JSONP
jsonp原理在于利用<script>标签没有跨域限制,通过<script>标签src属性,发送带有callback参数的get请求,服务器收到请求并把返回数据发回前端,浏览器进行解析,从而前端拿到数据。
优点
- 实现简单
- 兼容性好,可解决主流浏览器跨域数据访问问题
缺点
- 只能用于GET请求
- 存在XSS攻击可能
- 需要后端配合
1.3 postMessage
postMessaage是一个API,是可以跨域操作的window属性之一,可用于解决:
- 页面和其打开的新窗口数据
- 多窗口之间消息传递
- 页面与嵌套iframe消息传递
- 以上三个场景的跨域数据传递
二、前端安全问题
2.1 XSS:跨域脚本攻击
XSS攻击是一种代码注入攻击。攻击者通过在网站注入恶意脚本,使其在浏览器上运行,从而盗取用户信息如cookie等。
攻击者可以通过这种攻击进行以下操作:
- 获取页面数据,如DOM、cookie、localStorage
- DOS攻击,占用服务器资源,使用户无法访问服务器;
- 破坏页面结构;
- 流量劫持
防御方法
- 使用纯前端方式,不用服务器渲染
- 对需要插入到HTML代码做好充分转义。
- 对于数据获取渲染和字符串拼接的时候应该可能出现的恶意代码情况进行判断。
2.2 CSRF:跨站请求伪造
攻击者将用户诱导值一个第三方网站,然后该网站向被攻击网站发送跨站请求。如果用户保存了登录状态,攻击者可绕过后台用户验证,冒充用户向服务器执行操作。 本质上是利用cookie会在同源请求中携带发送给服务器的特点,以此实现用户冒充
防御措施
- 进行同源检测:
服务器根据http请求头origin或者referer信息判断是否为允许访问站点,进行过滤 - 使用token进行验证
- 对Cookie进行双重验证:
服务器在用户访问网页时,向请求域名注入一个cookie,内容为随机字符串,当用户再次发送请求时,将字符串从cookie中取出,添加到URL参数中,服务器对参数进行对比,进行验证。
三、浏览器输入url到页面显示过程
- DNS对域名进行解析
- 建立TCP连接(三次握手)
- 发送HTTP请求
- 服务器处理请求;
- 返回响应结果;
- 关闭TCP连接(四次挥手)
- 浏览器解析HTML
- 浏览器布局渲染
3.1浏览器对输入地址补全,然后DNS域名解析
如果搜索的是baidu.com,实际访问的还是http://www.baidu.com, 浏览器会将没输入的地址进行补充。
3.2 找到服务器地址,建立TCP连接(三次握手)
3.2.1 什么是TCP三次握手?
第一次握手: 客户端向服务端发送连接请求报文段。请求发送后,客户端进入SYN_SENT状态。
第二次握手: 服务端收到连接请求报文段后,如果同意连接,则会发送一个应答,发送完成后进入SYN_RECEIVED状态。
第三次握手: 当客户端收到连接同意应答之后,还要向服务端发送一个确认报文。客户端发送报文之后进入ESTABLISHED状态,服务端接收应答之后也进入ESTABLISHED状态,此时建立连接成功。
3.2.2 为什么要三次握手?两次不行吗?
- 三次握手是为了确认双方的接收能力和发送能力都正常
- 如果只有两次握手,则会出现下面情况:
如客户端发出连接请求,但因连接请求报文丢失而未收到确认,于是客户端再重传一次连接请求。后来收到了确认,建立了连接。数据传输完毕后,就释放了连接,客户端共发出了两个连接请求报文段,其中第一个丢失,第二个到达了服务端,但是第一个丢失的报文段只是在某些网络结点长时间滞留了,延误到连接释放以后的某个时间才到达服务端,此时服务端误认为客户端又发出一次新的连接请求,于是就向客户端发出确认报文段,同意建立连接,不采用三次握手,只要服务端发出确认,就建立新的连接了,此时客户端忽略服务端发来的确认,也不发送数据,则服务端一致等待客户端发送数据,浪费资源。
3.3 发送HTTP请求
浏览器会将请求包装成请求报文发送给服务器端。
3.4 服务器处理请求
服务器接收到请求之后,就会返回数据,比如一个html页面。
3.5 返回响应结果
如果服务器返回的content-type是accept中的任何一个,浏览器都能解析,并直接展示在网页上。
浏览器能直接处理很多种格式,并直接呈现在网页中,并不限于accept中规定的字段。
3.6 关闭TCP连接(四次挥手)
3.6.1 什么是四次挥手?
第一次挥手: 若客户端认为数据发送完成,则它需要向服务端发送连接释放请求。
第二次挥手: 服务端收到连接释放请求后,会告诉应用层释放TCP链接。然后会发送ACK包,并进入CLOSE_WAIT状态,此时表明客户端到服务端的连接已经释放,不再接受客户端发的数据了。但是因为TCP连接是双向的,所以服务端仍然可以发送数据给客户端。
第三次挥手: 服务端如果此时还有没发完的数据会继续发送,发送完毕之后会向客户端发送连接释放请求,然后进入LAST_ACT状态。
第四次挥手: 客户端收到释放请求之后,向服务端发送确认应答,此时客户端进入TIME_WAIT状态。该状态会持续2MSL时间,若该时间段没有服务端的重发请求,就会进入CLOSED状态。当服务端收到确认应答后,也会进入CLOSED状态。
3.7 浏览器解析HTML并渲染
-
获取 HTML ⽂件并进⾏解析,生成一棵 DOM 树(DOM Tree)
-
解析 HTML 的同时也会解析 CSS,⽣成样式规则(Style Rules)
-
根据 DOM 树和样式规则,生成一棵渲染树(Render Tree)
-
进行布局(Layout)(重排),即为每个节点分配⼀个在屏幕上应显示的确切坐标位置
-
进⾏绘制(Paint)(重绘),遍历渲染树节点,调⽤ GPU(图形处理器) 将元素呈现出来
四、HTTP
4.1 Get和Post请求的区别
- 应用场景: 一般Get请求用于对服务器资源不会造成影响的场景,比如说获取数据。Post请求则一般用于需要对服务器资源造成影响的情景,比如增加用户。
- 是否缓存: Get请求会被浏览器缓存,Post请求很少会被缓存。
- 传参方式不同: Get通过查询字符串传参,Post通过请求体传参。
- 安全性: Get请求可以请求的参数放入url向服务器发送,这样的做法相对于Post来说并不安全,因为请求的url会被保留在历史记录中。
- 参数类型: get参数只允许ASCII字符,Post参数支持传递更多数据类型(如文件、图片)
4.2 Ajax
用js异步发送网络请求
Ajax的核心是XMLHTTPRequest。它是一种支持异步请求的技术。 XMLHTTPRequest使您可以使用JavaScript向服务器提出请求并处理响应,而不阻塞用户。可以在页面加载以后进行页面的局部更新。
使用方法:
- 实例化ajax对象
- open():创建HTTP请求 第一个参数是指定提交方式(post、get);第二个参数是指定要提交的地址是哪;第三个参数是指是异步还是同步(true为异步,false表示同步)第四第五参数用于在HTTP认证中会用到,选填。
- 设置请求头
setRequestHeader(Stringheader,Stringvalue) (使用post方式才会使用到,get方法并不需要调用该方法) - 发送请求
send(content) 发送请求给服务器 如果是get方式,并不需要填写参数,或填写null如果是post方式,要把要提交的参数写上去。 - 注册回调函数
//(1).实例化ajax对象
let xhr = new XMLHttpRequest()
//(2).设置请求方法和地址
xhr.open("post", "http://www.liulongbin.top:3009/api/login")
//(3).设置请求头(post请求才需要设置)
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
//(4).发送请求 : 参数格式 'key=value'
xhr.send("username=admin&password=123456")
//(5).注册回调函数
// xhr.onload = function() {};
xhr.onreadystatechange = function() {
//onreadystatechange会触发多次,一般需要判断xhr.readState == 4 才获取响应数据
if (xhr.readyState == 4) {
console.log(xhr.responseText)
}
}
4.3 HTTP状态码
4.3.1 2XX 成功
- 200 OK,表示客户端发过来的请求被正确处理;
- 201 Created 请求已经被实现,而且有一个新资源已经依据请求的需求而建立。通常是在POST请求,或者是某些PUT请求之后创建了内容,进行的返回响应;
- 202 Accepted 请求服务器已经接受,但是尚未处理,不保证完成请求。适合异步任务或者说需要处理时间比较长的请求,避免HTTP链接一直占用;
- 204 No content,表示请求成功,但响应报文不含实体的主体部分;
- 205 Reset Content,表示请求成功,但响应报文不含实体主体部分,但是与204响应不同在于要求请求方重置内容;
- 206 Partial Content,进行的是范围请求,表示服务器已经成功处理部分GET请求,响应头中会包含获取的内容范围
4.3.2 3XX 重定向
-
301 moved permanently,永久性重定向,表示资源已经被分配了新的URL
-
302 found,临时性重定向,表示资源临时被分配了新的URL,支持搜索引擎优化
-
303 see other,表示资源存在着另一个URL,应使用GET方法获取资源
-
304 not modified,表示请求的资源没有被修改,可以直接从客户端的缓存中读取,而无需再次从服务器端请求。这通常被称为“未修改”或“缓存命中”响应。
需要注意的是,如果客户端的缓存中没有匹配的资源或服务器端的资源已经发生了变化,服务器将返回一个200状态码的响应,将新的资源发送给客户端。
-
307 temporary redirect,临时重定向,和302含义类似,但是期望客户端保持请求方法不变向新的地址发出请求。
4.3.3 4XX 客户端错误
- 400 bad request,请求报文存在语法错误(传参格式不正确)
- 401 unauthorized,表示发送的请求需要有通过HTTP认证的认证信息(没有权限)
- 403 forbidden,表示对请求资源的访问被服务器拒绝
- 404 not found,表示在服务器上没有找到请求的资源
- 408 Request Timeout 客户端请求超时
- 409 Confict 请求的资源可能引起冲突
5XX 服务器错误
- 500 ,表示服务端在执行请求时发生了错误
- 501, 表示服务器不支持当前请求所需要的某个功能
- 503, 表示服务器暂时处于超负载或停机维护,无法处理请求
4.4 URL语法格式
- 协议:http,规定数据出书的方式方法
- 域名:相当于IP地址,在网络环境中,唯一标识一台主机,用://与协议分隔开
- 端口号:在网络的主机上唯一标识一个进程,用:与域名分隔开
- 资源路径: 带访问的数据资源,与端口号用/分割开来
- 查询参数:传递给资源路径的参数,与资源路径用?分割开,可以有很多组值,每一对key:value用&分割开
- hash路径:用/#/分割查询参数和页面路由
五、DNS协议
5.1 DNS协议是什么
概念:DNS是域名系统缩写,提供的是一种主机名到 IP 地址的转换服务,就是我们常说的域名系统。它是一个由分层的 DNS 服务器组成的分布式数据库,是定义了主机如何查询这个分布式数据库的方式的应用层协议。能够使人更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。
作用:
将域名解析为IP地址,客户端向DNS服务器(DNS服务器有自己的IP地址)发送域名查询请求,DNS服务器告知客户机Web服务器的 IP 地址。
5.2 DNS解析域名过程
- 首先会从浏览器缓存中查找对应的IP地址,如果查找到直接返回,若找不到继续下一步
- 将请求发送给本地DNS服务器,在本地域名服务器缓存中查询,如果查找到,就直接将查找结果返回,若找不到继续下一步
- 本地DNS服务器向根域名服务器发送请求,根域名服务器会返回一个所查询域的顶级域名服务器地址
- 本地DNS服务器向顶级服务器发送请求,接受请求的服务器查询自己的缓存,如果有记录,就返回查询结果,如果没有就返回权威域名服务器发送请求,域名服务器返回对应结果
- 本地DNS服务器将返回结果保存在缓存中,便于下次使用
- 本地DNS服务器将返回结果返回给浏览器
六、浏览器存储
6.1 cookie
Cookie仅仅是一种存储在浏览器的数据格式,可以理解成一种数据载体,里面存放的是一些用户身份校验有关的数据,服务器在第一次收到请求后会在HTTP响应里,并添加头部Set-cookie,并添加标识(SessionID),并在之后每一次请求时,浏览器在HTTP请求里添加头部Cookie,并使用标识,这样可以使服务器进行识别并返回对应的数据。同时Cookie也是有时间限制的,过期之后需重新向服务器进行请求获得。
6.2 localstorage
localstorage是一种浏览器存储在本地的一种方式,一般情况下除非用户手动删除,将永久保存下来。
6.3 SessionStorage
SessionStorage也是一种浏览器存储本地的手段,适用于一种临时存储,当关闭网页时就会消失。
6.4 IndexedDB
IndexedDB是一种浏览器内置的客户端存储数据库,用于在Web应用程序中存储和检索大量数据。 IndexedDB的优点有以下几点:
- 支持存储大量数据。IndexedDB是一个高性能的数据库,可以存储大量结构化数据。
- 支持离线使用。IndexedDB的数据可以在离线状态下访问和更新,使得Web应用程序可以更好地支持离线使用。
- 支持事务操作。IndexedDB允许执行原子事务操作,确保数据的完整性和一致性。
- 支持索引查询。IndexedDB允许对存储数据建立索引,可以快速查询和检索数据。
IndexedDB的缺点包括:
- API复杂度较高。IndexedDB的API比较复杂,需要开发人员具备一定的数据库知识。
- 兼容性问题。IndexedDB在一些旧的浏览器中可能不被支持。
IndexedDB的安全性主要涉及以下两个方面:
- 存储数据的机密性:IndexedDB存储在客户端浏览器中,可能会遭受恶意攻击或窃取数据的威胁。为了保护数据的机密性,开发人员需要采取一些措施,例如使用加密算法对数据进行加密,限制数据访问权限等。
- 防止跨站点攻击(Cross-Site Scripting,XSS):XSS攻击可以通过注入恶意脚本来窃取数据或执行未经授权的操作。为了防止XSS攻击,开发人员需要在实现应用程序时使用安全的编程实践,例如输入数据验证和过滤,使用内容安全策略等。
除了以上两点,IndexedDB还具有一些内在的安全性措施,例如:
- 跨源策略:IndexedDB的跨源策略限制了只有在同源站点下才能访问数据库,避免了跨站点攻击的风险。
- 事务模型:IndexedDB的事务模型确保了数据操作的原子性和一致性,从而避免了数据损坏和数据访问冲突等问题。
七、cookie,session,token的区别
Cookie是一种数据存储载体,可以存储SessionID和token。
Session是一种服务器端的存储方式。
SessionId,不同的网站对每个用户的会话设定了时间和唯一的ID,一般保存在数据库。 当浏览器向服务器发送请求后,服务端会把SessionID和会话结束时间发给浏览器,并把SessionID加入到cookie里,浏览器拿到之后保存cookie以及里面的sessionID。
Token:
浏览器请求服务端之后,会生成token并返回浏览器,浏览器进行存储:
1.以Cookie形式存储,每一次发送请求就会把这个token发给服务器。
2.存储在storage中,并在每次请求时放在请求头里传给服务器储存。
八、SSR
SSR即服务器渲染,它通过服务器端渲染HTML页面,并将其传递给浏览器端展示,从而加速页面的加载速度,提升用户体验,相对于CSR,有以下优点:
- 更快的页面加载速度:SSR 可以让用户在浏览器中更快地看到页面内容,因为页面的 HTML 代码是在服务器端生成并发送到客户端,而不是在客户端浏览器中等待 JavaScript 加载和执行。
- 更好的 SEO:由于搜索引擎可以直接抓取服务器端渲染的页面,所以使用 SSR 可以提升网站的 SEO(Search Engine Optimization)效果。
- 更好的可访问性:某些搜索引擎、社交媒体和屏幕阅读器等可能无法执行 JavaScript,因此使用 SSR 可以保证这些机器人和用户能够正确地访问网站内容。
- 更好的用户体验:由于 SSR 可以减少首次加载时间,从而提升用户的体验。
九、SEO
SEO是指搜索引擎优化,是指通过优化网站的结构和内容,提高网站在搜索引擎中的自然排名,从而提高网站的曝光度、流量和转化率的一种网络营销方式。 优化方式:
- 网站结构优化:建立良好的网站结构,方便搜索引擎抓取和理解网站内容。
- 内容优化:编写原创、有价值的内容,包括文章、图片、视频等,提高用户体验和网站权重。
- 关键词优化:选择合适的关键词,并将其自然地融入到网站内容中。
- 外链建设:通过发布优质的内容吸引其他网站链接到自己的网站,提高网站权重和排名。
- 网站速度优化:优化网站加载速度,提高用户体验和搜索引擎爬取效率。
- 移动端优化:优化网站在移动设备上的访问体验,提高移动端流量。
- 社交媒体优化:积极在社交媒体平台上宣传网站内容,增加网站曝光度和流量。
十、多页面通信
10.1 如果在A页面使用B页面的功能有哪些方法?
- 使用iframe嵌入B页面。可以在A页面中使用iframe元素来嵌入B页面,从而可以在A页面中使用B页面的功能。
- 使用AJAX技术。可以在A页面中使用AJAX技术,向B页面发送请求,获取B页面的数据或执行B页面的功能。
- 使用Web组件技术。可以使用Web组件技术,将B页面的功能封装为自定义元素,然后在A页面中使用这些自定义元素,从而可以在A页面中使用B页面的功能。
- 使用跨窗口通信技术。可以使用postMessage等跨窗口通信技术,实现A页面和B页面之间的数据交换和功能调用。
10.2 iframe怎么解决跨域问题和数据存储问题?
当A页面和B页面不属于同一个域名时,使用iframe可能会面临跨域问题。为了解决这个问题,可以使用以下方法:
- 使用document.domain:如果A页面和B页面的二级域名相同,可以通过设置document.domain相同来解决跨域问题。
- 使用window.postMessage:使用postMessage API在A页面和B页面之间建立通信通道,实现数据传输和功能调用。
- 通过代理页面:在A页面和B页面之间添加一个代理页面,将A页面和B页面的数据传输都通过代理页面进行,从而避免跨域问题。
在使用iframe时,有时需要在A页面和B页面之间共享数据。为了解决这个问题,可以使用以下方法:
- 使用localStorage或sessionStorage:将需要共享的数据存储在localStorage或sessionStorage中,A页面和B页面都可以读取并使用这些数据。
- 使用postMessage API:通过postMessage API在A页面和B页面之间传输数据,实现数据的共享。
- 在同一个域名下使用cookie:如果A页面和B页面属于同一个域名,可以使用cookie来共享数据。
十一、浏览器性能
11.1 性能指标
11.1.1 FCP
首次内容绘制,浏览器首次绘制来自DOM的内容的时间,内容必须包括文本,图片,非白色的canvas或svg,也包括带有正在加载中的web字体文本。这是用户第一次看到的内容。
| FCP时间(秒) | 颜色编码 | FPC分数 |
|---|---|---|
| 0 - 2 | 绿色(快) | 75 - 100 |
| 2 - 4 | 橙色(中等) | 50 - 74 |
| 超过4 | 红色(慢) | 0 - 49 |
11.1.2 TTI
网页第一次完全达到可交互状态的时间点,浏览器已经可以持续的响应用户的输入,完全达到可交互的状态的时间是在最后一个长任务完成的时间,并且在随后的5s内网络和主线程是空闲的。从定义上来看,中文名称叫持续可交互时间或可流畅交互时间更合适。
| TTI时间(秒) | 颜色编码 |
|---|---|
| 0 - 3.8 | 绿色(快) |
| 3.9 - 7.3 | 橙色(中等) |
| 超过7.3 | 红色(慢) |
11.1.3 LCP
最大内容绘制,可视区域中最大的内容元素呈现到屏幕上的时间,用以估算页面的主要内容对用户的可见时间。img图片,video元素的封面,通过url加载到的北京,文本节点等,为了提供更好的用户体验,网站应该在2.5s以内或者更短的时间最大内容绘制。
| LCP时间(秒) | 颜色编码 |
|---|---|
| 0 - 2.5 | 绿色(快) |
| 2.5 - 4 | 橙色(中等) |
| 超过4 | 红色(慢) |
11.1.4 FID
首次输入延迟,从用户第一次与页面进行交互到浏览器实际能够响应该交互的时间,输入延迟是因为浏览器的主线程正忙于做其他事情,所以不能响应用户,发生这种情况的一个常见原因是浏览器正忙于解析和执行应用程序加载的大量计算的JavaScript。
| FID时间(毫秒) | 颜色编码 |
|---|---|
| 0 - 100 | 绿色(快) |
| 100 - 300 | 橙色(中等) |
| 超过300 | 红色(慢) |
11.1.5 TBT
总阻塞时间,度量了FCP和TTI之间的总时间,在该时间范围内,主线程被阻塞足够长的时间以防止输入响应。只要存在长任务,该主线程就会被视为阻塞,该任务在主线程上运行超过50毫秒。
线程阻塞是因为浏览器无法中断正在进行的任务,因此如果用户确实在较长的任务中间与页面进行交互,则浏览器必须等待任务完成才能响应。
| TBT时间(毫秒) | 颜色编码 |
|---|---|
| 0 - 300 | 绿色(快) |
| 300 - 600 | 橙色(中等) |
| 超过600 | 红色(慢) |
11.1.6 CLS
累计布局位移,CLS会测量在页面整个生命周期中发生的每个意外的布局移位的所有单独布局移位分数的总和,他是一种保证页面的视觉稳定性从而提升用户体验的指标方案。
用人话来说就是当点击页面中的某个元素的时候,突然布局变了,手指点到了其它位置。比如想点击页面的链接,突然出现了一个banner。这种情况可能是因为尺寸未知的图像或者视频。
| CLS时间(毫秒) | 颜色编码 |
|---|---|
| 0 - 0.1 | 绿色(快) |
| 0.1 - 0.25 | 橙色(中等) |
| 超过0.25 | 红色(慢) |
十二 HTTPS
12.1 HTTPS和HTTP的区别
- HTTP 是超文本传输协议,信息是明文传输,存在安全风险的问题。HTTPS 则解决 HTTP 不安全的缺陷,在 TCP 和 HTTP 网络层之间加入了 SSL/TLS 安全协议,使得报文能够加密传输。
- HTTP 连接建立相对简单, TCP 三次握手之后便可进行 HTTP 的报文传输。而 HTTPS 在 TCP 三次握手之后,还需进行 SSL/TLS 的握手过程,才可进入加密报文传输。
- 两者的默认端口不一样,HTTP 默认端口号是 80,HTTPS 默认端口号是 443。
- HTTPS 协议需要向 CA(证书权威机构)申请数字证书,来保证服务器的身份是可信的。
12.2 HTTPS解决了HTTP哪些问题
HTTP 由于是明文传输,所以安全上存在以下三个风险:
- 窃听风险,比如通信链路上可以获取通信内容,用户号容易没。
- 篡改风险,比如强制植入垃圾广告,视觉污染,用户眼容易瞎。
- 冒充风险,比如冒充淘宝网站,用户钱容易没。‘
HTTPS 在 HTTP 与 TCP 层之间加入了 SSL/TLS 协议,可以很好的解决了上述的风险:
- 信息加密:交互信息无法被窃取,但你的号会因为「自身忘记」账号而没。
- 校验机制:无法篡改通信内容,篡改了就不能正常显示,但百度「竞价排名」依然可以搜索垃圾广告。
- 身份证书:证明淘宝是真的淘宝网,但你的钱还是会因为「剁手」而没。
12.3 HTTPS是如何建立的?期间交互了什么?
SSL/TLS 协议基本流程:
- 客户端向服务器索要并验证服务器的公钥。
- 双方协商生产「会话秘钥」。
- 双方采用「会话秘钥」进行加密通信。
TLS 的「握手阶段」涉及四次通信,使用不同的密钥交换算法,TLS 握手流程也会不一样的,现在常用的密钥交换算法有两种:RSA 算法 (opens new window)和 ECDHE 算法 (opens new window)。
十三、 TCP
13.1 TCP和HTTP的关系
HTTP协议是建立在TCP协议之上的一种应用,必须先建立TCP才能进行HTTP交互。
13.2 TCP可以在前端使用吗?(阿里大淘宝)
在前端应用程序中,主要还是使用HTTP协议来进行网络通信。HTTP是建立在TCP协议之上的协议。
虽然在前端应用程序中不能直接使用TCP,但是可以使用TCP协议库来实现某些特定的功能,例如Websockets。Websockets是一种基于TCP协议的实时通信协议,允许客户端和服务器之间进行双向通信。
13.3 TCP怎么保证数据的准确性?
TCP 是通过下面几个特性保证数据传输的可靠性:
- 序列号和确认应答信号
- 超时重发控制
- 连接管理
- 滑动窗口控制
- 流量控制
- 拥塞控制
13.3.1 序列号确认应答信号
在TCP中,当发送端的数据到达接收主机时,接收端主句会返回一个已收到消息的通知,这个消息叫做确认应答。当发送端将数据发出之后会等待对端的确认应答。如果有确认应答,说明数据已经成功到达对端。反之,则数据丢失的可能性很大。
但是,如果在一定时间内发送端都没有得到确认应答ACK,发送端就会认为数据丢失,并进行数据重发。所以,即使产生了丢包,TCP仍然能保证数据能够到达对端,实现可靠的传输。
虽然目标主机通过重发数据可以提供可靠的传输,但是对于目标主机来说,反复收到相同的数据可能会是一个”灾难“,既浪费网络资源,还要耗资源对它处理。
所以,我们需要一种机制来识别是否已经接收到了这个数据包、又能够判断数据包是否需要接收。 为此我们引入了序列号。
序列号是按照顺序给发送数据的每一个字节(8位字节)都标上号码的编号。接收端查询接收数据 TCP 首部中的序列号和数据的长度,将自己下一步应该接收的序列号作为确认应答返送回去。通过序列号和确认应答号,TCP 能够识别是否已经接收数据,又能够判断是否需要接收,从而实现可靠传输。
13.3.2 超时重发控制
重发超时是指在重发数据之前,等待确认应答到来的那个特定时间间隔。如果超过这个时间仍未收到确认应答,发送端将进行数据重发。
此外,数据也不会被无限、反复地重发。达到一定重发次数之后,如果仍没有任何确认应答返回,就会判断为网络或对端主机发生了异常,强制关闭连接。并且通知应用通信异常强行终止。
13.3.3 连接管理
TCP是面向连接的通信协议,面向连接是指在数据通信之前先做好通信两端之间的准备工作。
因此,在数据通信之前,会通过TCP首部发送一个SYN包作为建立连接和等待确认应答,如果对端发来确认应答ACK,则认为可以进行通信,否则如果对端没有发送正确的ACK应答,那么就不会通信。
这就是我们常常说的 三次握手建立连接 和四次挥手关闭连接,
13.3.4 滑动窗口控制
TCP 以1个段为单位,如果每发送一个段进行一次确认应答,才能进行下一次通信,那这样的传输方式有一个缺点,就是包的往返时间(RTT)越长通信性能就越低.这种方式有点类似于数据库不能并发请求,只能一个挨一个的处理,自然这样的效率肯定是比并发低的
为解决这个问题,TCP 引入了窗口这个概念。确认应答不是以每个分段来确认,而是以更大的单位进行确认,转发时间将会被大幅地缩短。也就是说,发送端主机,在发送了一个段以后不必要一直等待确认应答,而是继续发送。
在使用了窗口控制中,如果出现了丢包怎么办呢?这里我们还是分两种情况分析:
-
1.确认应答ACK未能正确返回的情况
在这种情况下,数据是已经被对端主机成功接收了的,是不需要进行重新发送的。
然而,如果在没有使用窗口控制的前提下,没有收到确认应答包的数据包都会被重发。
但是,在使用了窗口控制以后,某些应答包即使丢失了也无需重发,这也提高了传输效率。 -
2.某个报文丢失的情况
如果当接收端主机接收到一个自己应该接收的序列号之外的数据包时,它会一直对当前接收到的数据包返回确认应答包。 发送端主机如果 连续 3 次 接收到同一个确认应答包,就会将其对应的数据重发,这种机制比之前提到的“超时重发”更加高效,所以被称之为“高速重发控制”
13.3.5 流量控制
所谓流量控制,就是让发送端不要发送的过快,让接收端能来得及接收
假设没有流量控制,发送端根据自己的实际情况发送数据,如果发送的速度太快,导致接收端的接收缓冲区很快填满了,此时发送端如果继续发送数据,接收端处理不过来,这时接收端就会把本来应该接收的数据丢弃,这会触发发送端的重发机制,从而导致网络流量的无端浪费。
TCP 利用滑动窗口实现流量控制的机制, 而滑动窗口大小是通过TCP首部的窗口大小字段来通知对方。
流量控制的具体操作就是:接收端会在确认应答发送ACK报文时,将自己的即时窗口大小rwnd(receiver window)填入,并跟随ACK报文一起发送过去。而发送方根据ACK报文里的窗口大小的值进而改变自己的发送速度。
13.3.6 拥塞控制
网络中的路由器会有一个数据包处理队列,当路由器接收到的数据包太多而一下子处理不过来时,就会导致数据包处理队列过长。此时,路由器就会无条件的丢弃新接收到的数据封包。 这就会导致上层的 TCP 协议以为数据包在网络中丢失,进而重传这些数据包,而路由器又会丢弃这些重传的数据包,如此以往,就会导致网络性能急剧下降,引起网络瘫痪。因此,TCP 需要控制数据包发送的数量来避免网络性能的下降。
有了TCP的滑动窗口控制,收发主机之间即使不再以一个“段”为单位,而是以一个“窗口”为单位发送确认应答信号,所以发送主机够连续发送大量数据包。然而,如果在通信刚开始的时候就发送大量的数据包,也有可能会导致网络的瘫痪。
在拥塞控制中,发送方维持一个叫做拥塞窗口cwnd(congestion window)的状态变量。拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化。 发送窗口取拥塞窗口和接收端窗口的最小值,避免发送接收端窗口还大的数据。
十四、重绘和回流
回流
重新生成布局,重新排列元素(重新计算各节点和css具体的大小和位置:渲染树需要重新计算所有受影响的节点);例如:改元素的宽高,会触发重排;
重绘
某些元素的外观被改变所触发的浏览器行为(重新计算节点在屏幕中的绝对位置并渲染的过程); 例如:修改元素的填充颜色,会触发重绘;
通过两者概念区别明显得知,回流要比重绘的成本大得多,我们应该尽量减少重排操作,减少页面性能消耗
可以造成重绘和回流的操作
下面情况会发生重绘:
- color
- border-style
- border-radius
- text-decoration
- box-shadow
- outline
- background
- ...
下面情况会发生重排:
-
页面初始渲染,这是开销最大的一次重排;
-
添加/删除可见的DOM元素;
-
改变元素位置;
-
改变元素尺寸,比如边距、填充、边框、宽度和高度等;
-
改变元素内容,比如文字数量,图片大小等;
-
改变元素字体大小;
-
改变浏览器窗口尺寸,比如resize事件发生时;
-
激活CSS伪类(例如::hover);
-
设置 style 属性的值,因为通过设置style属性改变结点样式的话,每一次设置都会触发一次reflow;
-
查询某些属性或调用某些计算方法:offsetWidth、offsetHeight等,除此之外,当我们调用getComputedStyl方法,或者IE里的 currentStyle 时,也会触发重排,原理是一样的,都为求一个“即时性”和“准确性”;
-
...