正在加载……
专注、离线、切勿分心

浏览器的高层结构

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

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


从输入url到页面展示

  1. 输入地址。在浏览器中输入网址的时候,浏览器就已经在智能的匹配可能得url了,他会从历史记录,书签等地方,找到已经输入的字符串可能对应的 url,然后给出智能提示,让你可以补全url地址。对于google的chrome的浏览器,他甚至会直接从缓存中把网页展示出来。
  2. 浏览器查找域名的 IP 地址。
1、浏览器首先解析域名,查看本地硬盘的 hosts 文件,如果有就直接使用 hosts 文件里面的 ip 地址。
2、本地的 hosts 文件没找到对应的 ip 地址,浏览器发出一个 DNS 请求到本地DNS服务器。本地DNS服务器一般都是你的网络接入服务器商提供。
3、本地DNS服务器首先查询它的缓存记录,如果缓存中有此条记录,就可以直接返回结果。如果没有,本地DNS服务器继续要向DNS根服务器进行查询。
4、根DNS服务器没有记录具体的域名和IP地址的对应关系,而是告诉本地DNS服务器,你可以到域服务器上去继续查询,并给出域服务器的地址。
5、 本地DNS服务器继续向域服务器发出请求,请求的对象是.com域服务器。.com域服务器收到请求之后,不会直接返回域名和IP地址的对应关系,而是告诉本地DNS服务器,你的域名的解析服务器的地址。
6、本地DNS服务器向域名的解析服务器发出请求,收到域名和IP地址对应关系,本地DNS服务器把IP地址返回给用户电脑,同时把这个对应关系保存在缓存中,以备下次别的用户查询时,可以直接返回结果,加快网络访问。

DNS负载均衡

当一个网站有足够多的用户的时候,假如每次请求的资源都位于同一台机器上面,那么这台机器随时可能会蹦掉。处理办法就是用DNS负载均衡技术,它的原理是在DNS服务器中为同一个主机名配置多个IP地址,在应答DNS查询时,DNS服务器对每个查询将以DNS文件中主机记录的IP地址按顺序返回不同的解析结果,将客户端的访问引导到不同的机器上去,使得不同的客户端访问不同的服务器,从而达到负载均衡的目的。例如可以根据每台机器的负载量,该机器离用户地理位置的距离等等。

3、浏览器向 web 服务器发送一个 HTTP 请求。

拿到域名对应的IP地址之后,浏览器会以一个随机端口(1024<端口<65535)向服务器的WEB程序(常用的有http,nginx等)80端口发起TCP的连接请求。这个连接请求到达服务器端后(这中间通过各种路由设备,局域网内除外),进入到网卡,然后是进入到内核的TCP/IP协议栈(用于识别该连接请求,解封包,一层一层的剥开),最终到达WEB程序,最终建立了TCP/IP的连接。

客户端向服务器发起http请求的时候,会有一些请求信息,请求信息包含三个部分:

请求方法URI协议/版本
请求头(Request Header)
请求正文
// 最后一个请求头之后是一个空行,发送回车符和换行符,通知服务器以下不再有请求头。

4、服务器的永久重定向响应

服务器给浏览器响应一个301永久重定向响应,这样浏览器就会访问http://www.google.com/ 而非http://google.com/。服务器一定要重定向而不是直接发送用户想看的网页内容,其中一个原因跟搜索引擎排名有关,如果一个页面有两个地址,就像http://www.yy.com/http://yy.com/,搜索引擎会认为它们是两个网站,结果造成每个搜索链接都减少从而降低排名。而搜索引擎知道301永久重定向是什么意思,这样就会把访问带www的和不带www的地址归到同一个网站排名下。还有就是用不同的地址会造成缓存友好性变差,当一个页面有好几个名字时,它可能会在缓存里出现好几次。

5、浏览器跟踪重定向地址

6、服务器处理请求

一些大一点的网站会将你的请求反向代理到服务器中,因为当网站访问量非常大,网站越来越慢,一台服务器已经不够用了。于是将同一个应用部署在多台服务器上,将大量用户的请求分配给多台机器处理。此时,客户端不是直接通过HTTP协议访问某网站应用服务器,而是先请求到Nginx,Nginx再请求应用服务器,然后将结果返回给客户端,这里Nginx的作用是反向代理服务器。同时也带来了一个好处,其中一台服务器万一挂了,只要还有其他服务器正常运行,就不会影响用户使用。

7、服务器返回一个 HTTP 响应

HTTP响应也由3个部分构成,分别是:

状态行:状态行由协议版本、数字形式的状态代码、及相应的状态描述,各元素之间以空格分隔。
响应头(Response Header)
响应正文

8、浏览器显示 HTML

在浏览器没有完整接受全部HTML文档时,它就已经开始显示这个页面了。

解析html

构建dom树 -> 构建render树 -> 布局render树 -> 绘制render树

浏览器在解析html文件时,会”自上而下“加载,并在加载过程中进行解析渲染。在解析过程中,如果遇到请求外部资源时,如图片、外链的CSS、iconfont等,请求过程是异步的,并不会影响html文档进行加载。
  解析过程中,浏览器首先会解析HTML文件构建DOM树,然后解析CSS文件构建渲染树,等到渲染树构建完成后,浏览器开始布局渲染树并将其绘制到屏幕上。这个过程比较复杂,涉及到两个概念: reflow(回流)repain(重绘)

DOM节点中的各个元素都是以盒模型的形式存在,这些都需要浏览器去计算其位置和大小等,这个过程称为reflow;当盒模型的位置,大小以及其他属性,如颜色,字体,等确定下来之后,浏览器便开始绘制内容,这个过程称为repain。

页面在首次加载时必然会经历reflow和repain。reflow和repain过程是非常消耗性能的,尤其是在移动设备上,它会破坏用户体验,有时会造成页面卡顿。所以我们应该尽可能少的减少reflow和repain。

当文档加载过程中遇到js文件,html文档会挂起渲染(加载解析渲染同步)的线程,不仅要等待文档中js文件加载完毕,还要等待解析执行完毕,才可以恢复html文档的渲染线程。因为JS有可能会修改DOM,最为经典的document.write,这意味着,在JS执行完成前,后续所有资源的下载可能是没法进行的,这是js阻塞后续资源下载的根本原因。所以平时的代码中,js是放在html文档末尾的。
  JS的解析是由浏览器中的JS解析引擎完成的,比如谷歌的是V8。JS是单线程运行,也就是说,在同一个时间内只能做一件事,所有的任务都需要排队,前一个任务结束,后一个任务才能开始。但是又存在某些任务比较耗时,如IO读写等,所以需要一种机制可以先执行排在后面的任务,这就是:同步任务(synchronous)和异步任务(asynchronous)。

defer

如果script标签设置了该属性,则浏览器会异步的下载该文件并且不会影响到后续DOM的渲染;如果有多个设置了deferscript标签存在,则会按照顺序执行所有的scriptdefer脚本会在文档渲染完毕后,DOMContentLoaded事件调用前执行。

后面的代码依赖当前脚本,就使用defer

image
async

async的设置,会使得script脚本异步的加载并在允许的情况下执行async的执行,并不会按着script在页面中的顺序来执行,而是谁先加载完谁执行。DOMContentLoaded事件不受async属性的脚本影响。

后面的代码不依赖当前脚本,就使用async

image image

http状态码

301 Moved Permanently 永久性重定向,浏览器在拿到服务器返回的这个状态码后会自动跳转到一个新的URL地址,这个地址可以从响应的Location首部中获取.(用户看到的效果就是他输入的地址A瞬间变成了另一个地址B)
302 Found 临时性重定向,和301一样,301表示旧地址A的资源已经被永久地移除了,不可访问,302表示旧地址A的资源还在(仍然可以访问),这个重定向只是临时地从旧地址A跳转到地址B。
400 Bad Request 表示客户端请求有语法错误,不能被服务器所理解
401 Unauthonzed 表示请求未经授权,该状态代码必须与 WWW-Authenticate 报头域一起使用
403 Forbidden 表示服务器收到请求,但是拒绝提供服务,通常会在响应正文中给出不提供服务的原因
404 Not Found 请求的资源不存在,例如,输入了错误的URL
500 Internel Server Error 表示服务器发生不可预期的错误,导致无法完成客户端的请求
503 Service Unavailable 表示服务器当前不能够处理客户端的请求,在一段时间之后,服务器可能会恢复正常

反向代理

客户端本来可以直接通过HTTP协议访问某网站应用服务器,网站管理员可以在中间加上一个Nginx,客户端请求Nginx,Nginx请求应用服务器,然后将结果返回给客户端,此时Nginx就是反向代理服务器。

img

CSRF

CSRF(Cross-site request forgery),跨站请求伪造。

攻击者盗用了你的身份,以你的名义发送恶意请求。CSRF能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账......造成的问题包括:个人隐私泄露以及财产安全。


CSRF原理

img

CSRF攻击必须满足两个条件:1、登录受信任网站A,并在本地生成Cookie。2、在不登出A的情况下,访问危险网站B。

CSRF攻击是源于WEB的隐式身份验证机制!WEB的身份验证机制虽然可以保证一个请求是来自于某个用户的浏览器,但却无法保证该请求是用户批准发送的。


CSRF的防御

CSRF的防御可以从服务端客户端两方面着手,防御效果是从服务端着手效果比较好,现在一般的CSRF防御也都在服务端进行。

服务端进行CSRF防御

1、Cookie Hashing(所有表单都包含同一个伪随机值),客户端页面增加伪随机数。攻击者不能获得第三方的Cookie(理论上),只能拿到浏览器的cookies,可以防止CSRF。

2、验证码

3、One-Time Tokens,不同的表单包含一个不同的伪随机值。需要注意“并行会话的兼容”,用户在一个站点上同时打开了两个不同的表单,用户只能成功地提交他最后打开的表单。

4、服务端核对令牌 token


XSS

XSS 即(Cross Site Scripting)中文名称为:跨站脚本攻击。XSS的重点不在于跨站点,而在于脚本的执行,恶意攻击者在web页面中会插入一些恶意的script代码。当用户浏览该页面的时候,那么嵌入到web页面中script代码会执行,达到恶意攻击用户的目的。

分类:

  1. 反射型
  2. 存储型
  3. DOM-based型

反射性和DOM-baseed型可以归类为非持久性XSS攻击。存储型可以归类为持久性XSS攻击

反射型XSS

一般指攻击者通过特定的方式来诱惑受害者去访问一个包含恶意代码的URL。当受害者点击恶意链接url的时候,恶意代码会直接在受害者的主机上的浏览器执行。

叫反射型XSS是因为这种攻击方式的注入代码是从目标服务器通过错误信息,搜索结果等方式反射回来的,非持久性XSS是因为这种攻击方式只有一次性。

反射型XSS的攻击步骤:

  1. 攻击者在url后面的参数中加入恶意攻击代码。
  2. 当用户打开带有恶意代码的URL的时候,网站服务端将恶意代码从URL中取出,拼接在html中并且返回给浏览器端。
  3. 用户浏览器接收到响应后执行解析,其中的恶意代码也会被执行到。
  4. 攻击者通过恶意代码来窃取到用户数据并发送到攻击者的网站。攻击者会获取到比如cookie等信息,然后使用该信息来冒充合法用户的行为,调用目标网站接口执行攻击等操作。

存储型XSS

将恶意代码上传或存储到服务器中,下次只要受害者浏览包含此恶意代码的页面就会执行恶意代码。

存储型XSS的攻击步骤

  1. 攻击者将恶意代码提交到目标网站数据库中。
  2. 用户打开目标网站时,网站服务器将恶意代码从数据库中取出,然后拼接到html中返回给浏览器中。
  3. 用户浏览器接收到响应后解析执行,那么其中的恶意代码也会被执行。
  4. 那么恶意代码执行后,就能获取到用户数据。

DOM-based型XSS

客户端的js可以对页面dom节点进行动态的操作,比如插入、修改页面的内容。如果用户在客户端输入的数据包含了恶意的js脚本的话,但是这些脚本又没有做任何过滤处理的话,那么我们的应用程序就有可能受到DOM-based XSS的攻击。

DOM-based型XSS的攻击步骤

  1. 攻击者构造出特殊的URL、在其中可能包含恶意代码。
  2. 用户打开带有恶意代码的URL。
  3. 用户浏览器收到响应后解析执行。前端使用js取出url中的恶意代码并执行。
  4. 执行时,恶意代码窃取用户数据并发送到攻击者的网站中,那么攻击者网站拿到这些数据去冒充用户的行为操作。调用目标网站接口执行攻击者一些操作。

DOM XSS 是基于文档对象模型的XSS。一般有如下DOM操作:

1. 使用document.write直接输出数据。
2. 使用innerHTML直接输出数据。
3. 使用location、location.href、location.replace、iframe.src、document.referer、window.name等这些。
eg:
    <script>
      document.body.innerHTML = "<a href='"+url+"'>"+url+"</a>";
    </script>

SQL注入

SQL注入是通过客户端的输入把SQL命令注入到一个应用的数据库中,从而执行恶意的SQL语句。

防范的方法:

  1. 可以使用预编译语句(PreparedStatement,这样的话即使使用sql语句伪造成参数,到了服务端的时候,这个伪造sql语句的参数也只是简单的字符,并不能起到攻击的作用。
  2. 数据库中密码不应明文存储的,可以对密码使用md5进行加密,为了加大破解成本,所以可以采用加盐的方式。

XSS攻击防范策略

cookie安全策略

在服务器端设置cookie的时候设置 http-only,这样就可以防止用户通过JS获取cookie。对cookie的读写或发送一般有如下字段进行设置:

http-only: 只允许http或https请求读取cookie、JS代码是无法读取cookie的(document.cookie会显示http-only的cookie项被自动过滤掉)。发送请求时自动发送cookie.
secure-only: 只允许https请求读取,发送请求时自动发送cookie。
host-only: 只允许主机域名与domain设置完成一致的网站才能访问该cookie。
X-XSS-Protection设置

该属性被所有的主流浏览器默认开启XSS保护。该参数是设置在响应头中目的是用来防范XSS攻击的。

0:禁用XSS保护。
1:启用XSS保护。
1;mode=block; 启用xss保护,并且在检查到XSS攻击是,停止渲染页面。
XSS防御HTML编码

将不可信数据放入到html标签内(比如div、span等)的时候需要进行html编码。采用正则的方式。

XSS防御HTML Attribute编码

将不可信数据放入html属性时(不含src、href、style 和 事件处理函数(onclick, onmouseover等))。需要进行HTML Attribute 编码。

XSS防御之 URL 编码

将不可信数据作为 URL 参数值时需要对参数进行 URL 编码,将参数值进行 encodeURIComponent 编码。

https://www.sojson.com/encodeurl.html?data="2021"
​ encodeURL: https://www.sojson.com/encodeurl.html?data=%222021%22
​ encodeURLComponent: https%3A%2F%2Fwww.sojson.com%2Fencodeurl.html%3Fdata%3D%222021%22

encodeURI()不会对本身属于URI的特殊字符进行编码,例如冒号、正斜杠、问号和井字而encodeURIComponent()则会对它发现的任何非标准字符进行编码。

开启CSP网页安全政策防止XSS攻击

CSP是网页安全政策(Content Security Policy)的缩写。主要用来防止XSS攻击。是一种由开发者定义的安全性政策申明,通过CSP所约束的责任指定可信的内容来源,通过 Content-Security-Policy 网页的开发者可以控制整个页面中外部资源的加载和执行。

<meta http-equiv="Content-Security-Policy" content="">
content指定信任的网站

HTTP(S)

HTTP:默认不加密的传输

HTTPS:超文本传输安全协议,默认加密的传输,=== HTTP + SSL/TLS

SSL:SSL(Secure Sockets Layer 安全套接字协议),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。TLS与SSL在传输层与应用层之间对网络连接进行加密。用以保障在Internet上数据传输的安全,利用数据加密(Encryption)技术,可确保数据在网络上的传输过程中不会被截取及窃听。

应用层HTTP --> TCP --> IP ...
应用层HTTP --> SSL/TLS --> TCP ---> IP ...

https传输前的准备:

服务器生成公钥和私钥
服务器将公钥交给CA (CA, Certificate Authority)
CA利用服务器传递过来的公钥生成证书
	CA自己会单独生成一对公钥私钥
	CA利用私钥对服务器传递过来的公钥进行加密
CA将证书发给服务器
服务器将公钥私钥证书存储在服务器上

https数据传输流程:

浏览器给服务器发送一个请求
服务器将CA发的证书交给浏览器
浏览器验证证书是否合法(不合法自动弹窗提示用户)
浏览器利用权威机构的公钥解密得到服务器的公钥
浏览器随机生成一个密钥,用于对称加密
浏览器利用服务器的公钥加密随机生成的密钥
浏览器将加密后的密钥发送给服务器
服务器利用自己的私钥解密得到密钥

后面通信都用这个密钥加密

HTTP1.0 和 2.0区别

  1. HTTP/2采用二进制格式而非文本格式
  2. HTTP/2是完全多路复用的,而非有序并阻塞的(HTTP1.x是顺序加载)——只需一个连接即可实现并行
  3. 使用报头压缩,HTTP/2降低了开销
  4. HTTP/2让服务器可以将响应主动“推送”到客户端缓存中

解析速度快

服务器解析 HTTP1.1 的请求时,必须不断地读入字节,直到遇到分隔符 CRLF 为止。而解析 HTTP2 的请求就不用这么麻烦,因为 HTTP2 是基于帧的协议,每个帧都有表示帧长度的字段。

HTTP/2 会将所有传输的信息分割为帧(frame),并对它们采用二进制格式的编码 ,其中首部信息会被封装到 HEADER frame,而相应的 Request Body 则封装到 DATA frame 里面。

多路复用

HTTP1.1 如果要同时发起多个请求,就得建立多个 TCP 连接,因为一个 TCP 连接同时只能处理一个 HTTP1.1 的请求。

在 HTTP2 上,多个请求可以共用一个 TCP 连接,这称为多路复用。同一个请求和响应用一个流来表示,并有唯一的流 ID 来标识。 多个请求和响应在 TCP 连接中可以乱序发送,到达目的地后再通过流 ID 重新组建。

HTTP 性能优化的关键并不在于高带宽,而是低延迟。TCP 连接会随着时间进行自我「调谐」,起初会限制连接的最大速度,如果数据成功传输,会随着时间的推移提高传输的速度。这种调谐则被称为 TCP 慢启动。由于这种原因,让原本就具有突发性和短时性的 HTTP 连接变的十分低效。

HTTP/2 通过让所有数据流共用同一个连接,可以更有效地使用 TCP 连接,让高带宽也能真正的服务于 HTTP 的性能提升。

首部压缩

在 HTTP/1 中,HTTP 请求和响应都是由「状态行、请求 / 响应头部、消息主体」三部分组成。一般而言,消息主体都会经过 gzip 压缩,或者本身传输的就是压缩过后的二进制文件(例如图片、音频),但状态行和头部却没有经过任何压缩,直接以纯文本传输。

随着 Web 功能越来越复杂,每个页面产生的请求数也越来越多,导致消耗在头部的流量越来越多,尤其是每次都要传输 UserAgent、Cookie 这类不会频繁变动的内容,完全是一种浪费。

头部压缩需要在支持 HTTP/2 的浏览器和服务端之间:

维护一份相同的静态字典(Static Table),包含常见的头部名称,以及特别常见的头部名称与值的组合;

维护一份相同的动态字典(Dynamic Table),可以动态的添加内容;

服务器推送

服务端推送是一种在客户端请求之前发送数据的机制。网页使用了许多资源:HTML、样式表、脚本、图片等等。在HTTP/1.x中这些资源每一个都必须明确地请求。这是一个很慢的过程。服务器必须等待浏览器做每一个请求,网络经常是空闲的和未充分使用的。

为了改善延迟,HTTP/2引入了server push,它允许服务端推送资源给浏览器,在浏览器明确地请求之前。一个服务器经常知道一个页面需要很多附加资源,在它响应浏览器第一个请求的时候,可以开始推送这些资源。这允许服务端去完全充分地利用一个可能空闲的网络,改善页面加载时间。就是HTTP2.0中,浏览器在请求HTML页面的时候,服务端会推送css、js等其他资源给浏览器,减少网络空闲浪费。

img

优先级

HTTP2 可以对比较紧急的请求设置一个较高的优先级,服务器在收到这样的请求后,可以优先处理。

流量控制

由于一个 TCP 连接流量带宽(根据客户端到服务器的网络带宽而定)是固定的,当有多个请求并发时,一个请求占的流量多,另一个请求占的流量就会少。流量控制可以对不同的流的流量进行精确控制。


http 1.0/ 1.1/ 2.0的不同

http 1.0(构建可扩展性)
a. 版本信息现在会随着每个请求发送(HTTP1.0 被追加到GET行)
b. 状态代码行也会在响应开始时发送,允许浏览器本身了解请求的成功或失败,并相应地调整其行为(如以特定方式更新或使用本地缓存)
c. 引入了HTTP头的概念,无论是对于请求还是响应,允许传输元数据,并使协议非常灵活和可扩展。
d. Content-Type标头告诉客户端实际返回的内容的内容类型。在Content-Type标头帮助下,增加了传输除纯文本HTML文件外的其他类型文档的能力。

http 1.1(标准化的协议)
HTTP/1.0的多种不同的实现运用起来有些混乱,HTTP1.1是第一个标准化版本,重点关注的是校正HTTP设计中的结构性缺陷:
a. 连接可以重复使用,节省了多次打开它的时间,以显示嵌入到单个原始文档中的资源。
b. 增加流水线操作,允许在第一个应答被完全发送之前发送第二个请求,以降低通信的延迟。
c. 支持响应分块。
d. 引入额外的缓存控制机制。
e. 引入内容协商,包括语言,编码,或类型,并允许客户端和服务器约定以最适当的内容进行交换。
f. 通过 Host 头,能够使不同的域名配置在同一个IP地址的服务器。
g. 安全性得到了提高

http 2.0(为了更优异的表现)
HTTP/2在HTTP/1.1有几处基本的不同:
a. HTTP2是二进制协议而不是文本协议。不再可读和无障碍的手动创建,改善的优化技术现在可被实施。
b. 这是一个复用协议。并行的请求能在同一个链接中处理,移除了HTTP/1.x中顺序和阻塞的约束。
c. 压缩了headers。因为headers在一系列请求中常常是相似的,其移除了重复和传输重复数据的成本。
d. 其允许服务器在客户端缓存中填充数据,通过一个叫服务器推送的机制来提前请求。

懒加载原理

实现图片懒加载其核心的思想就是将img的src属性先使用一张本地占位符,或者为空。然后真实的图片路径再定义一个data-set属性存起来,待达到一定条件的时将data-img的属性值赋给src。

const lazeLoad = function(imgs) {
  const observe = new IntersectionObserverEntry((entries) => {
    if(entries.length === 0) {
      observe.disconnect();
      return;
    }
    entries.forEach(entry => {
      entry.target.src = dataset.src;
      observe.unobserve(entry.target);
    })
  })
  imgs.forEach(img => observe.observe(img));
}

IntersectionObserver

可以自动"观察"元素是否可见,Chrome 51+ 已经支持。由于可见(visible)的本质是,目标元素与视口产生一个交叉区,所以这个 API 叫做"交叉观察器"。

var io = new IntersectionObserver(callback, option);
// callback是可见性变化时的回调函数,option是配置对象(该参数可选)。
var io = new IntersectionObserver(
  entries => {
    console.log(entries); // IntersectionObserverEntry对象,表示触发可见不可见的元素对象
  }
);
// 开始观察
io.observe(document.getElementById('example'));

// 停止观察
io.unobserve(element);

// 关闭观察器
io.disconnect();

IntersectionObserverEntry对象提供目标元素的信息,一共有六个属性。

{
  time: 3893.92,
  rootBounds: ClientRect {
    bottom: 920,
    height: 1024,
    left: 0,
    right: 1024,
    top: 0,
    width: 920
  },
  boundingClientRect: ClientRect {
     // ...
  },
  intersectionRect: ClientRect {
    // ...
  },
  intersectionRatio: 0.54,
  target: element
}
time:可见性发生变化的时间,是一个高精度时间戳,单位为毫秒
target:被观察的目标元素,是一个 DOM 节点对象
rootBounds:根元素的矩形区域的信息,getBoundingClientRect()方法的返回值,如果没有根元素(即直接相对于视口滚动),则返回null
boundingClientRect:目标元素的矩形区域的信息
intersectionRect:目标元素与视口(或根元素)的交叉区域的信息
intersectionRatio:目标元素的可见比例,即intersectionRect占boundingClientRect的比例,完全可见时为1,完全不可见时小于等于0

DNS

DNS的全称是域名系统(Domain Name System),是一种网络系统,它允许我们将对人类友好的名称解析为惟一的地址。

Domain Name

Domain Name 域名是我们用来关联换一个互联网资源的一个人性化的名字。举个例子,比如google.com就是一个域名。当然有些人觉得其中的google就是域名,但是我们通常把google.com这个组合称为域名。

Host 主机

有了域名,就可以定义独立的host主机,来通过域名访问不同的计算机和服务。举个例子,大多数域名拥有者会让他们的域名既能通过 (example.com)访问也能通过host主机定义的"www"(www.example.com)来访问。

DNS解析流程

把域名解析成IP地址的过程:

1, 首先,浏览器会从自身的DNS缓存中去查找(chrome://net-internals/#dns),如果没有则进行下一步
2, 然后,浏览器会先从操作系统里的DNS缓存中找,windows系统中,命令行 ipconfig/displaydns 查看,linux上的NSCD缓存服务;;;如果没有则进行下一步
3, 从计算机host文件里找,这个我们经常配置吧;;;如果没有则进行下一步
4, 请求本地域名服务器(可以认为是你的网络接入服务器商提供,比如中国电信,中国移动,阿里云等域名供应商),如果该服务器有缓存,则直接返回,若没有,则下一步。。。一般80%到这里就可以了(比如你申请一个域名,去阿里云,那么你肯定会写上域名所指向的IP啊)。
5, 若上一步都没命中,那么就需要向根域名服务器迭代请求了

DNS预解析

预解析的原理就是,当加载一个html时,会自动解析其中 a 标签所包含的 href 链接为IP地址。

// index.html
<html>
    <a href="test.baidu.com"></a>
</html>
当加载index.html时,会预先解析test.baidu.com,之后如果真的点击访问了test.baidu.com,就不需要DNS解析了。

注意,在HTTPS页面中,不会自动预解析,所以需要手动添加

<link rel="dns-prefetch" href="//img.alicdn.com"> <!--单条解析-->
<meta http-equiv="x-dns-prefetch-control" content="on"> <!--所有都-->

CDN原理

CDN的全称是 Content Delivery Network ,即内容分发网络。其目的是通过在现有的Internet流程中增加一层新的网络架构,将网站的内容发布到最接近用户的网络“边缘” ,使用户可以就近取得所需的内容,解决 Internet 网络拥塞状况,提高用户访问网站的响应速度。从技术上全面解决由于网络带宽小、用户访问量大、网点分布不均等原因,解决用户访问网站的响应速度慢的根本原因。

CNAME

CNAME就是你主域名A记录的小名

域名 www.xx.com → 111.111.111.111
www.credit.com → 111.111.111.111 // www.credit.com是主域名
// CNAME可以有多个
www.100fen.com → www.credit.com
www.baifen.com → www.credit.com
image-20210624113252863

DNS和CDN整体流程的总结

比如我们请求 www.credit.com 域名
1,首先,浏览器会从自身的DNS缓存中去查找(chrome://net-internals/#dns),如果没有则进行下一步
2,然后,浏览器会先从操作系统里的DNS缓存中找,windows系统中,命令行 ipconfig/displaydns 查看,linux上的NSCD缓存服务;;;如果没有则进行下一步
3,从计算机host文件里找,这个我们经常配置吧;;;如果没有则进行下一步
4,请求本地域名服务器(可以认为是 阿里云等域名供应商),
发现阿里云里面有进行过配置,CNMAE记录: www.credit.com → cdn.credit.com ,所以此时告诉浏览器转为请求 cdn.credit.com
此时,浏览器转为请求cdn.credit.com ,上面的1-3步还得再来一遍。。。
1-3步骤重复
4,请求本地域名服务器(可以认为是 阿里云等域名供应商),
发现阿里云里面有进行过配置,A记录:cdn.credit.com → 222.222.222.222 ,然后就把 IP 222.222.222.222 返回给浏览器。
5,浏览器得到了IP地址,注意这个IP地址,实际上是CDN负载均衡服务器的地址。。。继续请求这个地址
6,请求进入到了CDN负载均衡服务器后,服务器会根据算法策略等,返回一个最合适的文件缓存服务器IP地址,至于怎么选择合适的,看下面的优化
7,浏览器访问文件缓存服务器IP地址,最后得到文件资源

mkcert 生成本地 HTTPS 加密证书的工具

mkcert create-ca // 生成ca.crt 和 ca.key
mkcert create-cert //  生成cert.crt 和 cert.key
// 配置devserve
https: {
	key: fs.readFileSync(path.resolve(__dirname, 'cert.key'));
	cert: fs.readFileSync(path.resolve(__dirname, 'cert.cert'));
}
posted on 2021-06-14 23:10  正在加载……  阅读(338)  评论(0编辑  收藏  举报