浏览器原理总结速查

浏览器的存储

localStorage 注意点: localStorage 以字符串形式存储,存取 JSON 数据需配合 JSON.stringify() 和 JSON.parse() 遇上禁用 setItem 的浏览器,需要使用 try...catch 捕获异常

localStorage的作用域是限定在文档源级别的,它同样也受浏览器供应商限制。sessionStorage的作用域也限定在文档源中,不仅如此她还被限定在窗口中

cookie的作用域是通过文档源和文档路径来确定的。可通过path设置路径,domain设置域名。

注:cookie的path属性不能被用做访问控制机制。若一个页面想读取同一站点其他页面的cookie,只要简单地将其他页面以隐藏 <iframe> 的形式加载进来,随后读取对应文档的cookie就可以

输入URL到页面呈现发生了什么(中间过程是怎么样子的)?

(1)DNS解析:将域名解析为ip地址 (2)建立TCP连接: 客户端浏览器与WEB服务器建立TCP(传输控制协议)连接,三次握手【浏览器-->服务器,服务器-->浏览器,浏览器-->服务器】 (3)发送请求:请求报文 http协议的通信内容 (4)响应请求:响应报文 (5)渲染页面:dom树、css树、合并渲染树计算布局 绘制; (6)断开连接【非持久性】: TCP四次挥手。【浏览器-->服务器,服务器-->浏览器,服务器-->浏览器,浏览器-->服务器】

浏览器同源策略

协议+域名+端口

最流行的跨域方案

cors:跨域资源共享(CORS) 是一种机制,它使用额外的 HTTP 头来告诉浏览器 让运行在一个 origin (domain) 上的Web应用被准许访问来自不同源服务器上的指定的资源

**Nginx:**nginx是一款极其强大的web服务器,其优点就是轻量级、启动快、高并发(——通过反向代理——)proxy_pass:url配置

其他跨域方案:仅作为了解(基本应用为前后端分离通常情况下用上面两种方案可以解决)

(1)postMessage():方法允许来自不同源的脚本采用异步方式进行有限的通信,可以实现跨文本档、多窗口、跨域消息传递

(2)window.name + iframe:window.name属性值在不同的页面(甚至不同域名)加载后依旧存在,并且可以支持非常长的 name 值,我们可以利用这个特点进行跨域

(3)JSONP跨域:jsonp的原理就是利用<script>标签没有跨域限制,通过<script>标签src属性,发送带有callback参数的GET请求,服务端将接口返回数据拼凑到callback函数中,返回给浏览器,浏览器解析执行,从而前端拿到callback函数返回的数据。

<script>
    var script = document.createElement('script');
    script.type = 'text/javascript';
    // 传参一个回调函数名给后端,方便后端返回时执行这个在前端定义的回调函数
    script.src = 'http://www.domain2.com:8080/login?user=admin&callback=handleCallback';
    document.head.appendChild(script);
    // 回调执行函数
    function handleCallback(res) {
        alert(JSON.stringify(res));
    }
 </script>

(4)nodejs中间件代理跨域:node中间件实现跨域代理,原理大致与nginx相同,都是通过启一个代理服务器,实现数据的转发,也可以通过设置cookieDomainRewrite参数修改响应头中cookie中域名,实现当前域的cookie写入,方便接口登录认证

(5)location.hash + iframe跨域:a欲与b跨域相互通信,通过中间页c来实现。 三个页面,不同域之间利用iframe的location.hash传值,相同域之间直接js访问来通信

(6)document.domain + iframe跨域:此方案仅限主域相同,子域不同的跨域应用场景。实现原理:两个页面都通过js强制设置document.domain为基础主域,就实现了同域

(7)WebSocket :是一种双向通信协议,在建立连接之后,WebSocket 的 server 与 client 都能主动向对方发送或接收数据,连接建立好了之后 client 与 server 之间的双向通信就与 HTTP 无关了,因此可以跨域

浏览器的缓存(Http缓存)

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

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

304过程:强缓存失效,进入协商缓存阶段

  1. 浏览器请求资源时首先命中资源的Expires 和 Cache-Control,Expires 受限于本地时间,如果修改了本地时间,可能会造成缓存失效,可以通过Cache-control: max-age指定最大生命周期,状态仍然返回200,但不会请求数据,在浏览器中能明显看到from cache字样
  2. 强缓存失效,进入协商缓存阶段,首先验证ETag ETag可以保证每一个资源是唯一的,资源变化都会导致ETag变化。服务器根据客户端上送的If-None-Match值来判断是否命中缓存
  3. 协商缓存Last-Modify/If-Modify-Since阶段,客户端第一次请求资源时,服务服返回的header中会加上Last-Modify,Last-modify是一个时间标识该资源的最后修改时间。再次请求该资源时,request的请求头中会包含If-Modify-Since,该值为缓存之前返回的Last-Modify。服务器收到If-Modify-Since后,根据资源的最后修改时间判断是否命中缓存

DNS缓存:主要就是在浏览器本地把对应的 IP 和域名关联起来,这样在进行DNS解析的时候就很快

Service worker 实现的离线缓存就称为 Service Worker Cache,Service Worker 是一种独立于主线程之外的 Javascript 线程。它脱离于浏览器窗体,因此无法直接访问 DOM。

Push Cache(指 HTTP2 在 server push 阶段存在的缓存) 是缓存的最后一道防线。浏览器只有在 Memory Cache、HTTP Cache 和 Service Worker Cache 均未命中的情况下才会去询问 Push Cache。 Push Cache 是一种存在于会话阶段的缓存,当 session 终止时,缓存也随之释放

http2.x和http1.x的区别

明文: 明文指的是未被加密过的原始数据。 **密文:**明文被某种加密算法加密之后,会变成密文,从而确保原始数据的安全。密文也可以被解密,得到原始的明文。 **密钥:**密钥是一种参数,它是在明文转换为密文或将密文转换为明文的算法中输入的参数。密钥分为【对称密钥】与【非对称密钥】,分别应用在对称加密和非对称加密上。 **对称加密:**对称加密又叫做【私钥加密】,即信息的发送方和接收方使用同一个密钥去加密和解密数据。对称加密的特点是算法公开、加密和解密速度快,适合于对大数据量进行加密,常见的对称加密算法有DES、3DES、TDEA、Blowfish、RC5和IDEA。 

其加密过程如下: 明文 + 加密算法 + 私钥 => 密文 

解密过程如下: 

密文 + 解密算法 + 私钥 => 明文 对称加密中用到的密钥叫做私钥,私钥表示个人私有的密钥,即该密钥不能被泄露。 其加密过程中的私钥与解密过程中用到的私钥是同一个密钥,这也是称加密之所以称之为“对称”的原因。 由于对称加密的算法是公开的,所以一旦私钥被泄露,那么密文就很容易被破解; **对称加密的缺点:**密钥安全管理困难。 **非对称加密:**非对称加密也叫做公钥加密。非对称加密与对称加密相比,其安全性更好。对称加密的通信双方使用相同的密钥,如果一方的密钥遭泄露,那么整个通信就会被破解。 而非对称加密使用一对密钥,即公钥和私钥,且二者成对出现。私钥被自己保存,不能对外泄露。公钥指的是公共的密钥,任何人都可以获得该密钥。 用公钥或私钥中的任何一个进行加密,用另一个进行解密。 被公钥加密过的密文只能被私钥解密,过程如下: 明文 + 加密算法 + 公钥 => 密文, 密文 + 解密算法 + 私钥 => 明文 被私钥加密过的密文只能被公钥解密,过程如下: 明文 + 加密算法 + 私钥 => 密文, 密文 + 解密算法 + 公钥 => 明文 由于加密和解密使用了两个不同的密钥,这就是非对称加密“非对称”的原因。 **非对称加密的缺点:**加密和解密花费时间长、速度慢,只适合对少量数据进行加密。 在非对称加密中使用的主要算法有:RSA、Elgamal、Rabin、D-H、ECC(椭圆曲线加密算法)等。

HTTP概念:超文本传输协议,是一个基于请求与响应,无状态的,应用层的协议,常基于TCP/IP协议传输数据,互联网上应用最为广泛的一种网络协议,所有的WWW文件都必须遵守这个标准。 设计HTTP的初衷是为了提供一种发布和接收HTML页面的方法。

HTTP特点: 1、无状态:协议对客户端没有状态存储,对事物处理没有“记忆”能力,比如访问一个网站需要反复进行登录操作 2、无连接:HTTP/1.1之前,由于无状态特点,每次请求需要通过TCP三次握手四次挥手,和服务器重新建立连接。比如某个客户机在短时间多次请求同一个资源,服务器并不能区别是否已经响应过用户的请求,所以每次需要重新响应请求,需要耗费不必要的时间和流量。 3、基于请求和响应:基本的特性,由客户端发起请求,服务端响应 4、简单快速、灵活 5、通信使用明文、请求和响应不会对通信方进行确认、无法保护数据的完整性

HTTPS有如下特点: 1、内容加密:采用混合加密技术,中间者无法直接查看明文内容 2、验证身份:通过证书认证客户端访问的是自己的服务器 3、保护数据完整性:防止传输的内容被中间人冒充或者篡改

HTTP 与 HTTPS 的区别 1、HTTPS 协议需要到 CA (Certificate Authority,证书颁发机构)申请证书,一般免费证书较少,因而需要一定费用。 2、HTTP 是超文本传输协议,信息是明文传输,HTTPS 则是具有安全性的 SSL 加密传输协议。 3、HTTP 和 HTTPS 使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。 4、HTTP 的连接很简单,是无状态的。HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,比 HTTP 协议安全。(无状态的意思是其数据包的发送、传输和接收都是相互独立的。无连接的意思是指通信双方都不长久的维持对方的任何信息。)

***HTTPS概念:*HTTPS是一种通过计算机网络进行安全通信的传输协议,经由HTTP进行通信,利用SSL/TLS建立全信道,加密数据包。HTTPS使用的主要目的是提供对网站服务器的身份认证,同时保护交换数据的隐私与完整性。

HTTPS协议 = HTTP协议 + SSL/TLS协议; 在HTTPS数据传输的过程中,需要用SSL/TLS对数据进行加密和解密,需要用HTTP对加密后的数据进行传输,由此可以看出HTTPS是由HTTP和SSL【安全套接层协议】/TLS【安全传输层协议】一起合作完成的;

HTTPS的工作原理: 

1、客户端发起HTTPS请求 就是用户在浏览器里输入一个https网址,然后连接到server的443端口 

2、服务端的配置 采用HTTPS协议的服务器必须要有一套数字证书,可以自己制作,也可以向组织申请,区别就是自己颁发的证书需要客户端验证通过,才可以继续访问,而使用受信任的公司申请的证书则不会弹出提示页面(startssl就是个不错的选择,有1年的免费服务)。 这套证书其实就是一对公钥和私钥; 

3、传送证书 这个证书其实就是公钥,只是包含了很多信息,如证书的颁发机构,过期时间等等。 

4、客户端解析证书 这部分工作是由客户端的TLS来完成的,首先会验证公钥是否有效,比如颁发机构,过期时间等等,如果发现异常,则会弹出一个警告框,提示证书存在问题。 如果证书没有问题,那么就生成一个随机值,然后用证书对该随机值进行加密,就好像上面说的,把随机值用锁头锁起来,这样除非有钥匙,不然看不到被锁住的内容。 

5、传送加密信息 这部分传送的是用证书加密后的随机值,目的就是让服务端得到这个随机值,以后客户端和服务端的通信就可以通过这个随机值来进行加密解密了。 

6、服务端解密信息 服务端用私钥解密后,得到了客户端传过来的随机值(新的私钥),然后把内容通过该值进行对称加密,所谓对称加密就是,将信息和私钥通过某种算法混合在一起,这样除非知道私钥,不然无法获取内容,而正好客户端和服务端都知道这个私钥,所以只要加密算法够彪悍,私钥够复杂,数据就够安全。 

7、传输加密后的信息 这部分信息是服务段用私钥加密后的信息,可以在客户端被还原。 

8、客户端解密信息 客户端用之前生成的私钥(随机值)解密服务段传过来的信息,于是获取了解密后的内容,整个过程第三方即使监听到了数据,也束手无策。

**客户端:**客户端(Client)或称为用户端,是指与服务器相对应,为客户提供本地服务的程序DNS客户端、web客户端(Web客户端主要指web浏览器(Browser)、游戏客户端、移动客户端(Android和iOS)】 **服务端:**服务端是为客户端服务的,服务的内容诸如向客户端提供资源,保存客户端数据。

TCP【TCP 是全双工的】 和 UDP【OSI模型中,在第四层——传输层,处于IP协议的上一层】 区别:

链路层:负责封装和解封装IP报文,发送和接受ARP/RARP报文等。 网络层:负责路由以及把分组报文发送给目标网络或主机。 传输层:负责对报文进行分组和重组,并以TCP或UDP协议格式封装报文。 应用层:负责向用户提供应用程序,比如HTTP、FTP、Telnet、DNS、SMTP等。**

总结: TCP向上层提供面向连接的可靠服务 ,UDP向上层提供无连接不可靠服务。 虽然 UDP 并没有 TCP 传输来的准确,但是也能在很多实时性要求高的地方有所作为 对数据准确性要求高,速度可以相对较慢的,可以选用TCP;

浏览器的重绘和回流

**重绘(repaint):**屏幕的一部分要重绘。渲染树节点发生改变,但不影响该节点在页面当中的空间位置及大小。

譬如某个div标签节点的背景颜色、字体颜色等等发生改变,但是该div标签节点的宽、高、内外边距并不发生变化,此时触发浏览器重绘(repaint)。

**重排(reflow)【回流又称为重排】:**当渲染树节点发生改变,影响了节点的几何属性(如宽、高、内边距、外边距、或是float、position、display:none;等等),导致节点位置发生变化,此时触发浏览器重排(reflow),需要重新生成渲染树。 譬如JS为某个p标签节点添加新的样式:"display:none;"。导致该p标签被隐藏起来,该p标签之后的所有节点位置都会发生改变。此时浏览器需要重新生成渲染树,重新布局,即重排(reflow)。

重排和重绘的必然关系 注意:重排必将引起重绘,而重绘不一定会引起重排。

什么情况下会引起重排 当页面布局和几何属性改变时就需要重排;如下 1、添加或者删除可见的DOM元素; 2、元素位置改变——display、float、position、overflow等等; 3、元素尺寸改变——边距、填充、边框、宽度和高度 4、内容改变——比如文本改变或者图片大小改变而引起的计算值宽度和高度改变; 5、页面渲染初始化; 6、浏览器窗口尺寸改变——resize事件发生时;

如何减少和避免重排 Reflow 的成本比 Repaint 的成本高得多的多。一个节点的 Reflow 很有可能导致子节点,甚至父节点以及兄弟节点的 Reflow 。 在一些高性能的电脑上也许还没什么,但是如果 Reflow 发生在手机上,那么这个过程是延慢加载和耗电的。

1、直接改变className,如果动态改变样式,则使用cssText(考虑没有优化的浏览器);

2、让要操作的元素进行”离线处理”,处理完后一起更新; a) 使用DocumentFragment进行缓存操作,引发一次回流和重绘; b) 使用display:none技术,只引发两次回流和重绘; c) 使用cloneNode(true or false) 和 replaceChild 技术,引发一次回流和重绘;

3、不要经常访问会引起浏览器flush队列的属性,如果你确实要访问,利用缓存;

4、让元素脱离动画流,减少回流的Render Tree的规模;

节流和防抖(也属于性能优化一块)

节流和防抖只是浏览器处理事件的一种机制;

工具类方法的实现节流防抖的话借助第三方库 loadsh

防抖:(debounce)指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间 【时间戳版和定时器版】

/**
 * @desc 防抖函数
 * @param fn 函数
 * @param wait 延迟执行毫秒数
 * @param immediate true 表立即执行,false 表非立即执行
 */
function debounce(fn,wait,immediate) {
    let timeout;
    return function () {
        let ctx = this;
        let args = arguments;
        if (timeout) clearTimeout(timeout);
        if (immediate) {
            var callNow = !timeout;
            timeout = setTimeout(() => {
                timeout = null;
            }, wait)
            if (callNow) fn.apply(ctx, args)
        }
        else {
            timeout = setTimeout(function(){
                fn.apply(ctx, args)
            }, wait);
        }
    }
}

节流:(throttle)指连续触发事件但是在 n 秒中只执行一次函数。节流会稀释函数的执行频率 【非立即执行版和立即执行版】

 

/**
 * @desc 节流函数
 * @param fn 函数
 * @param wait 延迟执行毫秒数
 * @param type 1 表时间戳版,2 表定时器版
 */
function throttle(fn, wait ,type) {
    if (type === 1) {
        let previous = 0;
    } else if (type === 2) {
        let timeout;
    }
    return function() {
        let ctx = this;
        let args = arguments;
        if (type === 1) {
            let now = Date.now();
            if (now - previous > wait) {
                fn.apply(ctx, args);
                previous = now;
            }
        } else if (type === 2){
            if (!timeout) {
                timeout = setTimeout(() => {
                    timeout = null;
                    fn.apply(ctx, args)
                }, wait)
            }
        }
    }
}

应用场景:

防抖

  1. 输入框关键词搜索
  2. 登录、发短信等按钮避免用户点击太快,以致于发送了多次请求,需要防抖
  3. 调整浏览器窗口大小时,resize 次数过于频繁,造成计算过多,此时需要一次到位
  4. 文本编辑器实时保存,当无任何更改操作一秒后进行保存

节流

  1. scroll 事件,每隔一秒计算一次位置信息等
  2. 浏览器播放事件,每个一秒计算一次进度信息等
  3. input 框实时搜索并发送请求展示下拉列表,每隔一秒发送一次请求 (也可做防抖)

事件循环

JS是单线程运行的. 异步要基于回调来实现. event loop就是异步回调的实现原理

同步和异步任务分别进入不同的执行环境,同步的进入主线程,即主执行栈,异步的进入任务队列。主线程内的任务执行完毕为空,会去任务队列读取对应的任务,推入主线程执行。 上述过程的不断重复就是我们说的 Event Loop (事件循环)

event loop 过程: 同步代码,一行一行放在 Call Stack 执行 遇到异步,先“记录”下,等待时机(定时、网络请求等) 时机到了,就移动到 Callback Queue 如果 Call Stack 为空(即同步代码执行完),Event Loop 开始工作 轮询查找 Callback Queue,如有则移动到 Call Stack 执行 然后继续轮询查找(永动机一样)

DOM事件在event loop的执行:

同步代码,一行一行放在 Call Stack 执行 遇到点击事件 ,将点击事件的函数放在 Web APIs ,等待执行 所有的同步代码执行完,当callStack空了 同步执行结束 浏览器启动 Event Loop 机制, 开始轮询 Callback Queue 当用户触发点击事件,将Web APIs的 函数推到 Callback Queue Event Loop 机制在 Callback Queue 中找到了函数,并将函数 推到了 Call Stack 中执行函数内容,异步(setTimeout、ajax)等回调,基于Event Loop实现 *DOM事件也使用回调,基于Event Loop实现*

宏任务:(macrotask)主要包含:script( 整体代码)、setTimeout、setInterval、I/O、UI 交互事件、setImmediate(Node.js 环境)、requestAnimationFrame、postMessage

微任务:(microtask)主要包含:Promise、MutaionObserver、process.nextTick(Node.js 环境)

console.log('script start');

setTimeout(function() {
  console.log('setTimeout');
}, 0);

Promise.resolve().then(function() {
  console.log('promise1');
}).then(function() {
  console.log('promise2');
});

console.log('script end');

// 输出顺序  script start -> script end -> promise1 -> promise2 -> setTimeout 

 

console.log('script start');

setTimeout(function() {
  console.log('timeout1');
}, 10);

new Promise(resolve => {
    console.log('promise1');
    resolve();
    setTimeout(() => console.log('timeout2'), 10);
}).then(function() {
    console.log('then1')
})

console.log('script end');
// 输出顺序 script start -> promise1 -> script end -> then1 -> timeout1 -> timeout2

在microtask中不要放置复杂的处理程序,防止阻塞UI的渲染

  1. 可以使用process.nextTick处理一些比较紧急的事情
  2. 可以在setTimeout回调中处理上轮事件循环中UI渲染的结果
  3. 注意不要滥用setInterval和setTimeout,它们并不是可以保证能够按时处理的,setInterval甚至还会出现丢帧的情况,可考虑使用 requestAnimationFrame
  4. 一些可能会影响到UI的异步操作,可放在promise回调中处理,防止多一轮事件循环导致重复执行UI的渲染
  5. 在Node中使用immediate来可能会得到更多的保证

http协议中常用的请求方法

(1)GET:向特定的资源发起请求 (2)POST:向指定的资源提交数据进行处理请求,数据被包含在请求体中 (3)PUT:向指定资源位置上传其最新内容 (4)DELETE:请求服务器删除Request-URL所标识的资源 (5)HEAD:向服务器索与get请求一致的响应,只不过响应体不会被返回 (6)OPTIONS:返回服务器针对特点资源所支持的http请求方法 (7)TRACE:回显服务器收到的请求,主要用于测试或者诊断 (8)CONNECT:http/1.1协议中预留能够将连接改为管道方式的代理服务器 GET /url/list 查看 POST /url/create 创建
PUT /url/update 更新 DELETE /url/delete 删除
HEAD /url/is_exists 检查资源 PATCH /url/update_by_id 更新某些字段 OPTIONS /url/get_methods 检查请求方式

get和post的区别

GET产生一个TCP数据包;POST产生两个TCP数据包 get通过地址栏传输,post通过报文传输 get参数有长度限制(受限于url长度),而post无限制 get是获取数据的,而post是提交数据的 GET 用于获取信息,是无副作用的,是幂等的,且可缓存 POST 用于修改服务器上的数据,有副作用,非幂等,不可缓存

UDP和TCP有什么区别

TCP协议在传送数据段的时候要给段标号;UDP协议不需要 TCP协议可靠;UDP协议不可靠 TCP协议是面向连接;UDP协议采用无连接 TCP协议负载较高,采用虚电路;UDP采用无连接 TCP协议的发送方要确认接收方是否收到数据段(3次握手协议) TCP协议采用窗口技术和流控制

版权声明:
作者:wuhou123
链接:https://wuhou.fun/101.html
来源:前端网
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>
文章目录
关闭
目 录