这里会涉及到 Angular
的 ViewEncapsulation
,即控制视图的封装模式,主要分为三种,原生(Native
)、仿真(Emulated
)和无(None
)三种
这里会涉及到 Angular
的 ViewEncapsulation
,即控制视图的封装模式,主要分为三种,原生(Native
)、仿真(Emulated
)和无(None
)三种
最后更新于
2020-02-22
深浅拷贝也算是一个老生常谈的话题了,它也是一些面试题当中的高频题目,所以今天就抽些时间来深入的了解一下 JavaScript
中的深浅拷贝,也算是记录记录,不过在此之前我们先来了解一下可能会与深浅拷贝所混淆的『赋值』概念
Angular
中的管道主要是用来对字符串、货币金额、日期和其他显示数据进行转换和格式化,管道通常是一些简单的函数,可以在模板表达式中用来接受输入值并返回一个转换后的值,我们先来看看一些简单的使用场景
在正式展开之前,我们先来了解一下 Performance 接口,简单来说,它可以获取到当前页面中与性能相关的信息,主要用于 网页监控与程序性能,但是在本章当中就不详细展开了,具体的可以参考链接,有个概念即可
最后更新于
2020-04-12
最近在复习相关内容,打算从头的整理一下 Cookie
、Session
、Token
与 JWT
相关内容,彻底弄清它们的含义以及它们之间的区别,主要内容包括以下这些
Authentication
)Authorization
)Credentials
)Cookie
Session
Token
JWT
Cookie
和 Session
的区别Token
和 Session
的区别Token
和 JWT
的区别下面就让我们一个一个来进行了解,先从几个基本概念开始看起
最后更新于
2019-12-22
这其实是一个比较久远的面试题,原本针对于这个问题,参考了网上各种博文,查阅了许多资料,然后洋洋洒洒的整理出了好多步骤,自以为大致了解了整个过程,直到看到了 What happens when… 这篇文章以后,我决定把原文内容全部删除掉,直接搬运这篇文章的内容,然后从新的整理成自己比较好理解的方式放到这里,方便自己以后没事来复习复习,内容有所调整,主要是方便自己理解,如果想了解更为详细的流程可以参考原文
问题是这样的,当你在浏览器中输入 baidu.com
并且按下回车之后发生了什么?这个问题乍一眼看上去可能比较简单,发生什么?不就是在浏览器当中显现出对应的页面吗,虽然看上去是这样的,但是其实背后发生的事情却是非常之多的,大致的梳理一下分为以下这些,当然其中抛开了一些比如键盘输入,解析输入值等硬件处理的过程,我们在本章当中主要看的是数据传递过程和浏览器渲染相关部分的内容
DNS
查询ARP
过程HTTP
协议HTTP
服务器请求处理HTML
解析CSS
解析GPU
渲染DNS
缓存,看看自身的缓存中有没有 baidu.com
这个域名已经缓存的地址,这个缓存的时间大概只有一分钟,如果使用的是 Chrome
浏览器的话可以通过 chrome://net-internals/#dns
来查看浏览过的网站的 DNS
缓存有没有失效Hosts
里,如果找到,则它会停止搜索,然后解析也会到此结束Hosts
文件内也没有找到对应的配置项,那么浏览器就会发起一个 DNS
的系统调用,就会向本地主控 DNS
服务器(也就是你的宽带运营商提供,通常是本地路由器或者 ISP
的缓存 DNS
服务器)发送一条 DNS
查询请求DNS
服务器DNS
服务器和我们的主机在同一个子网内,系统会按照下面的 ARP
过程对 DNS
服务器进行 ARP
查询DNS
服务器和我们的主机在不同的子网,系统会按照下面的 ARP
过程对默认网关进行查询要想发送 ARP
(地址解析协议)广播,我们需要有一个目标 IP
地址,同时还需要知道用于发送 ARP
广播的接口的 MAC
地址,所以首先查询 ARP
缓存,如果缓存命中,我们返回结果,即目标 IP
为 MAC
,如果缓存没有命中,则
IP
地址是不是在本地路由表中的某个子网内,是的话,使用跟那个子网相连的接口,否则使用与默认网关相连的接口MAC
地址ARP
请求1 | // ARP Request: |
根据连接主机和路由器的硬件类型不同,可以分为几种情况,但是我们这里只看最简单的一种,也就是和路由器是直接连接的方式(其他方式可以参考原文),此时路由器会返回一个 ARP Reply
1 | // ARP Reply: |
现在我们有了 DNS
服务器或者默认网关的 IP
地址,我们可以继续 DNS
请求了
53
端口向 DNS
服务器发送 UDP
请求包,如果响应包太大,会使用 TCP
协议ISP DNS
服务器没有找到结果,它会发送一个递归查询请求,一层一层向高层 DNS
服务器做查询,直到查询到起始授权机构,如果找到会把结果返回它流程大致是下面这样的
com
域)com
域 DNS
服务器(拿到 baidu.com
)baidu.com
的 DNS
服务器(域名的注册商提供,万网,新网等)DNS
服务器(就拿到了 baidu.com
这个域名对应的 IP
地址)IP
地址,就把这个结果返回给浏览器www.baidu.com
对应的 IP
地址当浏览器得到了目标服务器的 IP
地址,以及 URL
中给出来端口号(HTTP
协议默认端口号是 80
, HTTPS
默认端口号是 443
),它会调用系统库函数 socket
,请求一个 TCP
流套接字,对应的参数是 AF_INET/AF_INET6
和 SOCK_STREAM
TCP segment
,目标端口会被加入头部,源端口会在系统内核的动态端口范围内选取TCP segment
被送往网络层,网络层会在其中再加入一个 IP
头部,里面包含了目标服务器的 IP
地址以及本机的 IP
地址,把它封装成一个 IP packet
TCP packet
接下来会进入链路层,链路层会在封包中加入 frame
头部,里面包含了本地内置网卡的 MAC
地址以及网关(本地路由器)的 MAC
地址,像前面说的一样,如果内核不知道网关的 MAC
地址,它必须进行 ARP
广播来查询其地址到了现在,TCP
封包已经准备好了,可以使用下面的方式进行传输
这里我们就不探讨传输方式的差异,以比较常见的光纤或以太网为例,在这种情况下信号一直是数字的,会被直接传到下一个 网络节点 进行处理
最终封包会到达管理本地子网的路由器,在那里出发,它会继续经过自治区域的边界路由器,其他自治区域,最终到达目标服务器,一路上经过的这些路由器会从 IP
数据报头部里提取出目标地址,并将封包正确地路由到下一个目的地,IP
数据报头部 time to live
(TTL
)域的值每经过一个路由器就减 1
,如果封包的 TTL
变为 0
,或者路由器由于网络拥堵等原因封包队列满了,那么这个包会被路由器丢弃
上面的发送和接受过程在 TCP
连接期间会发生很多次(也就是经典的三次握手与四次挥手的流程)
ISN
),将设置了 SYN
位的封包发送给服务器端,表明自己要建立连接并设置了初始序列号SYN
包,如果它可以建立连接SYN
位,表明自己选择了一个初始序列号ISN + 1
)复制到 ACK
域,并且设置 ACK
位,表明自己接收到了客户端的第一个封包+ 1
ACK + 1
ACK
位N
个 Bytes
的数据之后,将自己的 SEQ
序列号也增加 N
ACK
包,ACK
的值设置为接收到的数据包的最后一个序列号FIN
包FIN
包,并且发送自己的 FIN
包ACK
包来确认接收到了 FIN
如果浏览器使用 HTTP
协议而不支持 SPDY
协议,它会向服务器发送这样的一个请求
1 | GET / HTTP/1.1 |
其他头部当中包含了一系列的由冒号分割开的键值对,它们的格式符合 HTTP
协议标准,它们之间由一个换行符分割开来,HTTP/1.1
定义了关闭连接的选项 close
,发送者使用这个选项指示这次连接在响应结束之后会断开,例如
1 | Connection: close |
不支持持久连接的 HTTP/1.1
应用必须在每条消息中都包含 close
选项,在发送完这些请求和头部之后,浏览器发送一个换行符,表示要发送的内容已经结束了,服务器端返回一个响应码,指示这次请求的状态,响应的形式是这样的
1 | 200 OK |
然后是一个换行,接下来有效载荷(payload
),也就是 www.baidu.com
的 HTML
内容,服务器下面可能会关闭连接,如果客户端请求保持连接的话,服务器端会保持连接打开,以供之后的请求重用
如果浏览器发送的 HTTP
头部包含了足够多的信息(例如包含了 Etag
头部),以至于服务器可以判断出,浏览器缓存的文件版本自从上次获取之后没有再更改过,服务器可能会返回这样的响应
1 | 304 Not Modified |
这个响应没有有效载荷,浏览器会从自己的缓存中取出想要的内容,在解析完 HTML
之后,浏览器和客户端会重复上面的过程,直到 HTML
页面引入的所有资源(Images
,CSS
,favicon.ico
等等)全部都获取完毕,如果 HTML
引入了 www.baidu.com
域名之外的资源,浏览器会回到上面解析域名那一步,按照下面的步骤往下一步一步执行,请求中的 Host
头部会变成另外的域名
HTTPD
(HTTP Daemon
)在服务器端处理请求/响应,最常见的 HTTPD
有 Linux
上常用的 Apache
和 nginx
,以及 Windows
上的 IIS
HTTPD
接收请求HTTP
请求方法(GET
,POST
,HEAD
,PUT
,DELETE
,CONNECT
,OPTIONS
或者 TRACE
)直接在地址栏中输入 URL
这种情况下,使用的是 GET
方法baidu.com
/
(因为我们没有请求 baidu.com
下的指定的页面,因此 /
是默认的路径)baidu.com
接受 GET
方法GET
方法(根据 IP
地址,身份信息等)/
,所以会访问首页文件当服务器提供了资源之后(HTML
,CSS
,JavaScript
,Images
等),浏览器会执行下面的操作
HTML
,CSS
,JavaScript
1 | 构建 DOM 树 ==> CSSOM ==> Render Tree ==> 渲染 ==> 布局 ==> 绘制 |
浏览器渲染引擎从网络层取得请求的文档,一般情况下文档会分成 8kb
大小的分块传输,HTML
解析器的主要工作是对 HTML
文档进行解析,生成解析树
解析树是以 DOM
元素以及属性为节点的树,DOM
是文档对象模型的缩写,它是 HTML
文档的对象表示,同时也是 HTML
元素面向外部(如 JavaScript
)的接口,树的根部是 Document
对象,整个 DOM
和 HTML
文档几乎是一对一的关系
由于 HTML
不能使用常见的自顶向下或自底向上方法来进行分析,所以浏览器创造了专门用于解析 HTML
的解析器,解析算法在 HTML5
标准规范中有详细介绍,算法主要包含了两个阶段,标记化(tokenization
)和树的构建
解析结束之后浏览器开始加载网页的外部资源(CSS
,Images
,JavaScript
文件等),此时浏览器把文档标记为可交互的(interactive
),浏览器开始解析处于异步(deferred
)模式的脚本,也就是那些需要在文档解析完毕之后再执行的脚本,之后文档的状态会变为 complete
,浏览器会触发 load
事件
CSS
文件和 <style>
标签包含的内容以及 style
属性的值CSS
文件都被解析成一个样式表对象(StyleSheet object
),这个对象里包含了带有选择器的 CSS
规则,和对应 CSS
语法的对象CSS
解析器可能是自顶向下的,也可能是使用解析器生成器生成的自底向上的解析器DOM
节点树创建一个渲染树(DOM Tree + CSSOM
,这里是泛指),并计算每个节点的各个 CSS
样式值,然后构建每个节点的坐标floated
,位置有 absolutely
或 relatively
属性的时候,会有更多复杂的计算,详见 CSS 2 和 CSS Current WorkCPU
,也可能使用图形处理器 GPU
GPU
用于图形渲染时,图形驱动软件会把任务分成多个部分,这样可以充分利用 GPU
强大的并行计算能力,用于在渲染过程中进行大量的浮点计算渲染结束后,浏览器根据某些时间机制运行 JavaScript
代码或与用户交互,类似 Flash
和 Java
的插件也会运行,尽管我们请求的主页(/
)里面可能没有,但是这些脚本可以触发网络请求,也可能改变网页的内容和布局,产生又一轮渲染与绘制
如果全部完成以后,至此就把一个完整的页面呈现给了用户
this
是 JavaScript
语言的一个关键字,它代表函数运行时自动生成的一个内部对象,只能在函数内部使用,随着函数使用场合的不同,this
的值会发生变化,但是有一个总的原则,那就是 this
指向的是『调用函数的那个对象』
一般来说,一个函数是可以通过外部代码调用的一个子程序(或在递归的情况下由内部函数调用),像程序本身一样,一个函数由称为函数体的一系列语句组成,值可以传递给一个函数,函数也可以返回一个值
Update your browser to view this website correctly. Update my browser now