前言
开宗明义,本瓜深知汝之痛点:前端面试常识点太杂,卿总为了面试而面试,忘了记,记了又忘,循环往复,为此叫苦连天。
来,让本瓜带领各位都稍稍回忆一下,自己曾经在学生时代回忆元素周期表的光辉年月。
氢、氦、锂、铍、硼、碳、氮、氧、氟、氖、钠、镁、铝、硅、磷、硫、y f u G K ? Y氯、氩、钾、钙、钪、钛、钒、铬、猛、铁、钴、镍、铜、) k 锌…E f ! ~ n…
咱当初记这前三十位元素,是死记硬背的吗?答案是否定的,机敏@ y J z G的咱们用到了 串联回忆法{ Y 1 h k ) S 。
必定是像这样或相[ i q | n E . 似这样去记:
第一周期:氢 氦 ———— 轻嗨:悄悄的打个了招呼:嗨!
第二周期:锂 铍 硼 碳 氮 氧 氟 氖 ———— 你皮捧碳 蛋养l a ? g福奶:你很皮,手里捧了一把碳。鸡k @ v a [ 1 Q蛋能够( ^ b e $滋补福气的奶妈
第三周期:钠 镁 铝 硅 磷 硫 氯 氩 ———— 那美人桂林留绿牙:那美人在桂林留绿色的牙齿
第四周期:钾 钙 钪 钛 钒 铬 猛 铁 钴 镍 铜 锌 ———— 贾盖坑太凡哥 猛铁骨裂痛心:“贾` X 0 C p J盖”坑了“= _ j a N F太凡哥”,导致猛男铁汉骨头碎裂很痛心
串联联想与二元链式联想回忆的办法有相似之处,便是都要经过想象、发明和编故事来协助咱们达到双0 e F脑学习和回忆的意图。—— 出处
有木有?本瓜记住尤为清楚,以上串联起来的谐音故事简直能够写出一个狗血剧本了。尤其是“那美人(钠镁铝)”简略三Z v _ ] v @ 字似乎就能激起青春期的荷尔蒙。如此,学习能不有兴趣吗?兴趣是最好的教师!想遗忘都难啊!
于是A ~ d T [乎,本瓜类^ H v G @比归化,将自己遇到过– V m 2 x ~ j的高频面试问题运用串联联主意进行了“串联”收拾,以期构成体系,与各位同好共享。
上a ( / x * Q Z 8图!

- 本文脑图支撑:processon
我是掘金安东尼,愿一向与你同行!
我的个站:https://tuaran.site
My Blog:httl d p R |ps://tuaran.github.io
串联一:
从输入URL到页面加载产生了什么?
从输入URL到页面加载产生了什么?
此题是经典中的经典,可发掘的点十分之多,亦十分之深。
一图胜万言

- 原创脑图,转载请阐明出处
串联常识点M k S : 7 H:URL解析} j c u C、DNS查询、TCP握手、HTTP恳求、浏A S f览器处理回来报文、页面烘托
串联回忆:合计六步,归并为一句话来回5 – r (忆:UDTH,处理M i f y X m f M E回来加烘托。P , X I V v q r
“UDTH”X z 4 s Q i @ 即UR 2 F + G l ( SL解析、DNS查询、TCP握手u 6 n ] r、HTTP恳求,
“处理回来加烘托”,即浏览器处理回来报文,和页面烘托。
一起,本瓜倾情在z n 2 N Q : + R脑图上标示了每个进程或许3 ] I W h考察的常识点“关键词F 5 k W”,真的是个个关键,不容错失!
一、URL 解析
URL(Uniform Resource Locatq h V b w r @ r vor),一致资源定位符,用于定位互联网上资源,俗称网址。
// 示例引自 wikipedia
hierarchical part
┌───────────────────┴─────────────────────┐
authori& L 8 , _ M 4ty path
┌───────────────┴───────────────┐┌───┴────8 @ b┐
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
└┬┘ └───────┬───────┘ └────┬────┘ └┬4 i c┘ └────────d 1 C ] L c U─┬─────────┘ └──┬──┘
scheme user i{ 1 N ~ x F onformation host port query fragment
scheme - 界说因P s ; K i + * H B特网服务的类型。常见的协议有 htz L p B m &tp、https、ftd . W m e ! . r p、fil ^ `e,
其间最k * t 3 c N {常见的类型是 http,而 https 则是进行加密的网络传输。
host - 界说域主机(http 的默许主机是 www)
domain - 界说因特D M % / l f a 4网域名,比如 baidu.com
port - 界@ ^ D O o 3 3说主机上的端口号(http 的默许端口号是 80)
path - 界说服D 7 l h ] l i务器上的途径(假如省掉,则文档有必要位于网站的根目录中)。% d t q o h m
filename - 界说文档/资源的称号
query - 即查询参数
fragment - 即 # 后的hash值,一般用来定位到某个方位
更多可见:
- URL RFC
- Wikipedia-URI
URL 编码
一般来说,URL 只能运用英文字K q X , } , 1母、阿拉伯数字D @ { ,和某些标点符号,不能运用其他文字和T U R符号。此在 URL RFC 已做硬性规矩。
这意味着,假如URL) z s E B D中有汉字,就有必要A A 6 z –编码后运用。可是麻烦的是* e v 3 g,RFC 1738没有规矩具体的编码办法,而是交给运用程序(浏览器)自己决定。这导致”URL编码”成为了一个紊乱的领3 : & :域。
阮教师早在 2010 年已解说了:关于URL编码- 阮一峰
这儿可直接L s 3 Q看结论:浏览器对 URL 编码会呈现差异然后构成紊乱,所以假定咱们运用 J+ S S % 1 Aavascript 预先对 URL 编码,然后再6 % 2 e o W R 9向服务器提交。由于Javascript 的输出总是共同的,这样就确保了服务器R u a m – ) 3 J w得到的数据是格局l p X ) | _ f &一致的。
咱们常运用到:encodeUq Z 2 7 I @RI()、encodeURIComponent();前者对整个 URL 进行 utf-8 编码,后者是对 URL 部分进行编码。
本瓜请问:你能清楚的解说 ASCII、Uni] g d ; H d w ecode、UTF-8、GBK 意义和联络; } 8 S吗?
或许咱们并不太了解咱们常见、常用的东西。
类型 | 意义 |
---|---|
ASCII | 8位一个字节,1个字节{ x ^ s K n表明一个字符.即: 2 ** 8 = 256,所以ASCII码最多只能1 . S 1表明256个字符。 |
Unicode | 俗称万国码,把全部的语言8 V j E E t一致到一个编码_ ? n T % U G里.处理了ASCII码的约束以及乱码的问题。unicode码一般是用两个字节表明一~ { L B个字符,特别冷僻的用四个字节表明一个字符。 |
UTF-8 | “可变长的编码办法”,假如是英文字符,则选用ASCII编码,占用一个字节。假如是常用汉字,就占用三个字节# T % n p,B h L U | ] $ d D假如是冷僻的字就占用4~6个字节。 |
GBK | 国内版别,一个中文字符 == 两个字节8 V W B r l 英y ( ^ Z ) t R文是一个字节 |
强缓存、洽谈缓存
言外之音:本瓜起初是将强缓存、洽谈缓存放在第三步 “HTTP 恳求”中,后来了解到:假= ^ P ! = H如命中了T S K强缓存则可不再走DNS解析这步。遂将其归到此处。浏览器^ E ( : o I a g强缓存是依照ip仍是域名缓存的?
强缓存、洽谈缓存是必考题。具体流程如下:
-
浏览器在加载资源时,依据恳求头的 expires和 cache-cw { ^ontrol判别是否命中强缓存,是则直接从缓存读取资源,不会发恳求到服务器。8 # #
exj b 6 – _pires:HTTP/1[ J 6 b @ g.0 时期,依据比照本地时刻和服务器时刻来判别。
cache-control:HTTP/1.1 时期,依据相对时刻来判别,如设置max-age,单位为秒。
-
假如没有命中强缓存,浏览器必定会发送一个8 N , 7恳求到服务器,经过Etag和LaU I Y 8 :st-Modified-If验证资源是否命中洽谈缓存,假如命中,服务器会将这个恳求回来(304),告诉浏览器从缓存中读取数据。
【ETag、If-None-Match】成对:Etag 是服务器回来给浏览器的,If-None-Match 是浏览器恳求服务器的。经过比照二者来判别,它们记载的是:3 7 c文件生成的仅有标识。
【Last-ModifiF ; ] H 0 T M ued,If-Modified-Since】成对:Mode 2 Y ` x z G o yified-Since 是服务器回来给浏览器的,If-Modified-Since 是浏览器恳求服务器的。经过比照二者来判别,它们记载的是:最终修正时刻。
注:ETag 的优先级比 Last-Modified 更高。大部分 web 服务器都默许开启洽, r W @ V B T 0 b谈缓存,并且是一起启用【ETag、If-None-Match】和 【Last-Modified,If-Modified-Since】。
-
假如前面两者都没有命中,直接从服务器加载资源。
综上,强缓存和洽谈缓存假如命中,都是从客b ) B D N 2 #户端缓存中加载资源,而不是从服务器加载资源数据;不同的是:强缓存U 5 a v 6 )不会发恳求到服务器,z p B 2 h $ L T洽谈缓存会发恳求到服务器进行比照判别得出是否命中。
- 借一个流程图,暂未找到实在出处,保存引证阐O { O C Q ? ~明坑位。

以上还有另一个关键,便是cache-contrv % ; gol的值的分类:如“no-cache”、“no-store”、“priva{ M * cte”等,需求细扣。此处仅暂列二三、作初步释义。
- no-cache: 跳过其时的强缓存,发送HTTP恳求,即直z w e U 0 B w接进入洽谈缓存阶段。
- no-store:不进行任何办法的缓存。
- private: 这种状况便是只需浏览器能缓存了,中间的代理服务器不能缓存。
更多可见:
- Cache-ContJ 2 ! E V Y c W jrol – MDN
- 缓存(二)——c q O浏览器缓存机制:强缓存、洽谈缓存 #41
二、DNS查询
递归查询
DNS 解析 URL(自右向左) 找到对应的 ip
// 例如:查找www.google.com的IP地址进程(+ b u h 1 g O %真实的网址是www.google.com.):
// 根域名服务器 -> com尖端域名服务器 -> google.com域名服务器 -> www.google.com对应的ip
.r . O 5 -> .com -> google.com. -> www.google.com.
这是一个递归查询的进程。

关于根域名的更多常识,可见
根域名的常识-阮一峰。
DNS 缓存
请记住:有0 Q / . G O : ( 1 DNS 的当地,就有 DNS 缓存。
DNS存在着多级缓存,从距离浏览器的距离排序的话,有以下几种:) : 0
1.浏览器缓存 2.体系缓存 3.路由器缓存 4.IPS 服务器缓存 5.根域名服务器缓存 6.尖端域名服务器缓存X Y _ ! e / 7.主域名服务器缓存。
查看缓存:
-
浏览器查看 DNS 缓存:chrome://net-internal} w A 6 1 + 0 5s/#dns
-
win10 体系查看 DNS 缓存:win+R => cmd => ipconfig /displaydns
DNS 负载均衡
DNS负载均衡技能的完结原理是在DNS服务器中为同一个主机名装备: ; m g多个IP地址,在应对DNS查询时,DNS服务器对每个查询将以DNS文件中主机记载的IP地址按次序回} R ) A ` k m 5来不同的解析成果,将客户端的拜访引导到不同的机器上去,使得不同的客户端拜访不同的% + H / _ J M V服务器,+ O % G 5 x然后达到负载均衡的意图。—— 百科
三、TCP握手
DNS解析回来域i I w # g ? X I名的I| / k h t V n DP之后,接下来便是浏览器要和该IP树立TCP衔接了。
言外之音:TCP 的相关常识在大学根底课程《核算机网络》都有,本瓜内心苦:出来混的迟早是要还的……
TCP/IP 模型:链路层-网络层-传输层-运用层。
与之对应,OZ = & * R 2 ^ _ 6SI(开放式体系互联模型)也不能忘。一般以为 OSI 模型的最上面三层(运用层、表明层和会话层)对Q N [ % Z应 TCP/IP 模型中的运用层。, . R A t F Zwiki
在 TCP/IPu Q ! x 模^ . I $型中,像常用的 HTTP/HTTPS/SSH 等协议都在运用层上。

三次握手、四次挥手
所谓三次握手(Three-way Handshake)V l m,是指树立一个 TCP 衔接时,需求客户] a W I端和服务器总共发送3个包。
三次握手就跟早期打电话时的状况一样:1、A:听得到吗?2、B:听得到,你呢?3? M 1、A:我也听到了。然后才开端真实对话。
1.f C k m i 1 F M i 第一次握手t K r(SYN=1, seq=x):
客户端发送一个 TCP 的 SYN 标志方位1的包,指明客户端打1 C K . 3 ;算衔接的服务器的端口,以及初始Y [ G ; 5 h序号 X,保存在包头的序列号(Sequence Number)字段里。
发送完毕后,客户端进入 SYN_SET f k /ND 状况。
2. 第2次握手(SYN=1, ACK=1, seq=y, ACKnum=x+1):
服; 3 _ % n U务器发回承认包(ACK)应对。即 SYN 标志位和 ACK 标志位均为1。服务器H W ( * G端选择自己 ISN 序列号,放到 Seq 域里,一起% 5 0 _将承认序号(AcknowleX # d b U #dgement Number)设置为客户的 ISN 加1,即X+1。 发送完毕后,服务器端进入 SYN_RCV* % / B - - q p iDP . * b u ? 0 Z 状况。
3. 第三次握手(ACK=1,$ : /ACKnum=y+1)
客户端再次发送承认包(ACK),SYN 标志位为0,ACK 标志位为12 I ? . C J,并且把服务器发来 ACK3 u E 的序号字段+1,放在确定字段中发送给对方,并且@ | | s w P在数据段放写ISN的; ] r E s y Y w+1
发送完毕后,客户端进入 ESTABLISHED 状况,当服务器端接纳到这个包时,也进入 ESTc j = m qABLISHED 状况,TCP 握手完毕。

所谓四次挥手(Four-way handshake),是~ 5 4 3 ? : 0 }指 TCP 的衔接的撤除需求发送四个包。
四次挥手像教师拖堂的场景:1、学生说:教师,下课了。2、教师:好,我知道了,我说完这点。3、教师:好了,说完了,下课吧。4、q T c h M 6 F学生:谢谢教师,教师再会。
1. 第一次挥手(FIN=1,seq=x)
假定客户端想要封闭衔接,客户端发送一个 FIN 标志方位为1的包,表明自己现已没有数据能够发送了,可是依然能够承受数据。
发送完毕后,客户端进入 FIN_WAIT_1 状况。
2. 第2次挥手(ACK=1,ACKnum=x+1)
服务器端承认客户端的 FINa + Z - a t = 包,发送一个承认包,表明自己承受到了客户端封闭衔接的恳求,但还没有准备好封闭衔接。
发送完毕后,服务器端进入 CLOSE_WAIT 状况,客户端接纳到这个承认包之后,进入 FIN_WAIT_2 状况,等待服务器端封闭X x `衔接。
3. 第三次挥手(FIN=1,seq=y)
服务器端准备好封闭衔接时,向客户端发送完毕衔接恳求,FIN 置为1。
发送完毕后,服务器端进入 LAST_ACK 状况,等待来自客户端的最终一个ACK。
4. 第四次挥手(ACK=1,ACKnum=y+1)
客户端接纳到来自服务器端的封闭恳求,发送一个承认包,并进入 TIME_WAIT状况,等待或许呈现的要求重传的 ACK 包。
服务器端接纳到这个承认包之后,封闭衔接,进入 CLOSED 状况。
客户端等待了某个固定时刻(两个最大e k 2 5 G e z j A段生命周期,2MSL,2 Maximum Segment Lifet7 o u W d a ~ Zime)之后,没有收到服务器端的 ACK ,以为服务器端现已正常封闭衔接,于是自己也封闭衔接,进入 CLOSED 状况。

你若问我:三次握手、四次挥手的具体内容太难记了,还记不记?本瓜答:进大厂是必要的。
动图来历:两张动图-彻底了解TCP的三次握手与四次挥手
流量操控(滑动窗口)
为了增加网络的吞吐量,想将数据包一起发送过去,完结“流量操控”,这时分便产生了“滑动窗口”这种协议。
滑动窗口允许发送方在收到接纳方的承认之前发送多个数据段。窗口巨细决定了在收到意图地承认之前,一次能够传送的数据段的最大数目。窗口巨细越大,主机一次能够传输的数据段就越多。当主机传输窗口巨细数意图数据段后,就有r * z } H s & w l必要等收到承认,才干够再传下面的数据段。
窗口的巨细在通讯两边P j P / { k i ;衔接期间是可变的,通讯两边能够经过洽谈动态地修正窗口巨细。改动窗口巨细的仅有依据,便是接纳端缓冲区的巨细。
拥塞操控
需求>供应 就会产生拥塞
经过“拥塞窗口”、“慢发动”、“快速重传”、“快速康复”动态处0 3 ?理。
TCP 运用多种拥塞操控战略来避免雪崩式拥塞。TCP会为每条衔接维护一个“拥塞窗口”来约束或许在端对端间传输的未承认分组X n * C U总数x ! E量。这相似 TCP 流量操控机制中运用的滑动窗口。TCP在一个衔接初始化或超时后运用一种“慢发动”机制来增加拥塞窗口的巨细。它的起始值一般为最大分段巨细(Maximum segment size,MS, #S)的两倍,尽管名为$ F = I m ! b C D“慢发动”,初始值也相当低,但其增加极快:当每个分段得到r R 0 ] K 5 =承认时,拥塞窗口会增加一个MSS,使得在每次K Z A往返时刻(round-trip time,RTT)内拥塞窗口能高B : s 0 T L I g效地e 5 M v 3 2双倍增加。—— TCP拥塞操控-wikipedia
滑动窗. [ 4口(流量操控)和拥塞操控里的原理性的东西太多,M 5 4 U U l y本瓜表明? @ 9 ~ I y J无力,暂时要求极力去了解去回忆。
引荐阅览:
- 一篇带你读懂TCP之“滑动窗口”协议
- TCP流量操控、拥塞操控
四、HTTP恳求
HTTP是万维网的数据通讯的根底 —— 维基百科
HTTP恳求报文是由三部分组成: 恳求行, 恳求报} 4 I ;头和恳求正文。
HTTP呼应报文也是由三部分组成: 状况码, 呼应报头和呼应报文。
HTTP、HTTPS
HTTP 和 HTTPS 的差异?
HTTP报文是包裹在TCP报文中发送的Y J y,服务器端收到TCP报文时会解G l 1 q 9包提取出HTTP报文/ j L b H r j T。可是这个进程中存在必定的危险,HTTP报文是明文,假如中间被截取的话会存在一些信息走漏的危险。
假如在进入T0 n *CP报文之前对H` 7 e k /TTP做一次加密@ Q f Z $ Y b就能够处理这个问题了。HTTPS协议的实质便是HTTP + SSL(or TLS)。在HTTP@ G B Y 9 s & h报文进入TCP+ T g x B B . f _报文之前,先运用SSL对HTTP报文进行加密。从网络的层级结构看它位于HTTP协议与TCP协议之间。

HTTP2
http2 是彻底兼容 http/1.x 的,并在此根底上增加了 4 个首要新特性:P J f
- 二进制分o 9 m u I y W 4帧:http/1.x 是一个文本协议,而 httR b b { , J P Q fp2 是一个二进制协议。: P r
- 头部紧缩:h} p F | f $ & H fttp/1.x 中恳求头根本不变,http2 中+ A % s ^ e ~ o M提出了一个 HPACK 的紧缩办法,用于削减 http header 在每次恳求中耗费的流v 5 ! d 2 * 4 =量。
- 服务端推送:服M S ; l $ M Q v 7务端主意向客户端推送数据。
- 多路复用:https d % o K Y/1.x,每个 http 恳求都会树立一个 TCP 衔接;http2,全部的恳求都会共用一个TCt t L ! 5 HP衔接。
更多了解,可见 HTTP2 详解
GET、POST
直观差异:
- GET 用来获取数据,POST 用来提交数据。
- GET 参数有长度约束(受限于urE I t kl长度,具体的数值取决于浏览器和服务器的约束,最长2M),而 POu J { } [ r , ^ nST 无约束。
- GET 恳求的数据会附加在s _ j 5 N UR; 4 g X D e ;L 上,以”?”切割,多个参数用”&”衔接,而 POST 恳求会把恳求的数据放在 HT[ , ` HTP 恳求体中。都可被抓包。
- GET 恳求会保存在浏览器历史记载中,还或许保存在 WEB 服务器的日志中。
隐藏差异(存在浏览T Q ^器差异):
- GET 产生一个 TCP 数据包;POST 产生两个 TCP 数据包。
更多了解:
RESTful API 规划攻略 – 阮一峰
Keep-Aliv% g _ 0 r U !e
咱们都知道运用 Keep-Alive 是为了避免重新树立衔接。
现在大部分浏览器都是用 htR K g , ^ f jtp1.1 协议,默许都会主张 Keep-Alive 的衔接恳求了,所所以否能完结一个完整的 Keep-Alive 衔接就看服务器设置状况。
HTTP 长衔接不或许一向坚持,它有两个参数,例如 Keep-Alive: timeout=5, max=100,表明这个TCP通道能够坚持_ | ) Y i c K y5秒,max=100,表明这个长衔接最多接纳100次恳求就断开。
Keep-Alive 形式发送数据 HTTP 服务器不会自动断开衔接,全[ # [ 6 b部不能运用回来EOF(-1)来判别。
基于此,抛问题:当 HTTP 选用 keepalive 形式,当客户端向服务器产生恳求之后,客户端怎样判别服务器的数据现[ B R x A已产生完结?
-
运用音讯首部字段 Conent-Ley ^ M L Angth:Conent-Length表明实体内容长度,客户端能够依据这个值来判别数据是否接纳完结。
-
运用音讯S 3 e首部字段 Transfer-Encoding:假如是动态页面,服务器不或许预先知道内容巨细,这时就能够运用Transfer-EncH : ,oding:chunk 形式来传E J B ~ K y输数据了。即假如要一边产生数据,一边发给客户端,服务器就需求运用”Transfer-Encoq 8 L 2 z k U L Pding: chunked”这样的办法来替代Content-Length。chunked 编码的数据在最终有一个空 chunked 块,表明本2 ~ S – g次传输数据完毕
本瓜之前面试腾讯 PCG 就被问到 Transs n N n wfer-Encoding:c/ F h _hunk 这个,请咱们格外留意。
参阅:
- Keep-Alive – MDN
- HTTP长衔接和短衔接
五、浏览器处理回{ , y Z d H L s来报文
状况码
1xx:指示信息–表明恳求已接纳,持续处理。
2xx:成功–表明恳求已被成功接纳、了e d Q a p & d l 解、承受。
3xx:重定向–要完结恳求有必要进行更进一步的操作。
4xx:客户端过错–恳求有语法过错或恳求无法完结。
5xx:服务器端过错–服务器未能完结合法的恳求。
平时遇到比较常见的状况码有:200, 204, 301, 302, 304, 400, 401, 403, 404, 422, 500。
切分回来头和回来体(腾讯 PCG 考点)
这儿的考点其实和 http keep-alive 中的问题重合,可是仍是想着重强调,由于本瓜掉过这个坑,一再点出,以示后人。
最终归为k D X g a这个问题:Detect end of HTTP request body – stackoverflow
答复:
1. If the client sends a message with Transfer-Encoding: Chunked, you will need to parse the som1 J ; u x r Aewhat complil * A * u 2 A e lcated chunked transfer encoding syntax. You don8 [ V k not really have much choice in t# @ ) Ghe matter -- if tZ _ 2 Z i Qhe client is sending in this format, you have to receive it. When the client is using this approach, you can detect the end of the body by a chunk with a length of 0.
2. If the client insteadS U | Q sends a Content-Length, you must us! x ;e that.
即:怎样获取 HTTP 回来体?
-
先把 header 直到 \r\n\r\n(两个换行)整个读取,即整个恳求头;
-
假如回来 Transfer-Encoding: Chunked,则读取,直到遇到空x = Z A I 5 U : chunked 块,则完毕。
-
假如回来 Cb 1 5 c X . 3 I Lontent-Length,则读从恳求头的结尾开端核算 Content-Length 长度的字节。
-
其他状况,等待回来。8 | b D b f &
了解更多:HTTP 之呼应篇
本地数据存储
- cookie:4K,能够手动设置失效期。
- localStorage:5M,除非手动铲除,不然一向存在。
- sessionStorage:5M,不能够跨标签拜访,页面封闭就收拾。
- indexedDy W | A 9 w ZB:h v o K k z浏览器端数据库,无限容量w t 4 k x a,除非手动铲除,不然一向存在。
- Web SQL:联络数据库,经过SQL句子拜访(现已被扔掉)。
浏览器缓存方位
按优先级从高到低:
- Sec L rvice Worker:实质是一个web worker,是独立Q , e 3 K + A P于网页运转的脚本。
- Memory? q Y q } U U Cache:Memory Cache指的是内/ f _ u存缓存,从功率上讲它是最快的_ ^ R U。
- Disk Cache:Disk Ca( ! # # c n Y 8che便是存储在磁盘中的缓5 [ l存,从存取功率上讲是比内存缓存慢的,可是他的优势在于存储容量和存储时长。
- Push Cache:即推送缓存,是 HTTT – 5 t i nP/2 的内容。
更多:
- servL F h + y V Z ;ice worker 静态资源离! K )线缓存实践
- HTTP/2 push is tougher than I thought
离线缓存:
<html lang="en" manifest="U A R O C e y } Aoffline.appcache">Z V r
HTML5-离线缓存(Application Cache)
注:“浏览器缓存方位”和“离线缓存”了解相关,有个概念/形象即可。
六、页面烘托
CssTree+DomT. m G u ] f ^ n 5ree
本瓜知道你知道J 5 k进程是这样的:
dom tree + css tree = render tree => layout =>painting?
可是你真的吃透了吗?
HTML → DOM树L c 6 a 7 ~ | X ^ 转化进程:
- 解码:浏览器从磁盘或网络读取HTMLQ ^ . 2 6 = L的原始字节,然后依据指定的文件编码格局(例如 UTF-8)将其转换为相应字符
- 令牌化:浏览器把字符转化成W38 $ E @C HTML5 标准指定的各种切当的令牌,比如””S Z V / j、””以及其他在尖括号内的字符串。每个令牌都有特别的意义以及它自己的一套规Y y ?矩
- 词法剖析:生u { q成的令牌转化为方C u V s w * L L A针,这个方针界说了它们的特色及规矩
- DOM树构建:最终,由于$ & N r o rHTML符号界说了$ z ] j i M V )不同标签之间的联络(某些标签嵌套在其他标签中),创立的方针在树状的数据结构中相互链接,树状数据结构也捕获了原始标签界说的父子联络:HTML方针是body方针的父方针,body是p方I U p针的父方针等等

CSS → CSSOM树 转化进程类同以上
CSSOM只输出包括有款式的节点,最终输出为:

Rek U I @ G wnder Tree (生成烘托树,核算可见节点和款式)
- 不包括Header 、 script 、meta 等不可见的节点
- 某些经过 CSS 隐藏的节点在烘托u k +树中也会被疏忽,比如运用了 display:n% 1 ; ) r 3 )one 规矩的节点,而visibility: hidden仅仅视觉不可见,仍占有空Q w $ N间,不会被疏忽。
layout:依照盒子模型,核算出每个节点在屏幕中的方位及尺度
painting:依照算出来的规矩,经过显卡,把内容% 1 ( ` u A J ( 画到屏幕上。
回流、重绘
回流:
当可见节点方位及尺度产生改动时会产生回流
重绘:
改动某个元素的背景色、文字颜色、边框颜色等等不f q n影响它周围或内部布局的特色时,屏幕的一部分要重画,可是元素的几何尺度没有变。
这儿本瓜再抛两个问题。
Q1:浏览器在什么时分向服务器发送获取css、js外部文件的恳求?
A1:解析DOM时碰到外部链接,假如还有connect. r P ` ? 0 , 0ion,则马上触发下载恳求。
Q2:CSSOM DOM JavaScript 三者堵塞联络?
A2:CSSOM DOM互不影响,JavaScript会堵塞DOM树的构建但JS前的HTML能够正常解析成DOM树,CSSOM的构建会堵塞JavaScript的履行。对此句存疑?
- css 加载的堵塞状. = y ( Z j –况:& P 0 M & B
css加载不会堵塞DOM树的解析
// DOM解析和CSS解析是两个并行的进程,所以这也解说了为什么CSS加载不, . v = + U R 8 :会堵塞DOM的解析。` f z K Scss加载会堵塞DOM树的烘托
// 由于Render Tree是依靠于DX $ `OM Tree和CSSOM Tree的,所以他有必要等待到CSSOM Tree构建8 N : 4完结,也便是CSS资源加载完结(或许CSS资源加载失败)后,才干开端烘托。因而,CSS加载是会堵塞Dom的烘托的。css加载会堵塞后边jc z d Z R !s句子的履行
// 由于js或许会操作之前的Dom节点和css款式,因而浏览器会维持html中css和js的次序。因而,款式表会在后边的js履行前先加载履行完毕。所以css会堵塞后边js的履行。
参阅阅览:
- css加载会构成堵塞k G z * ) z吗?
- 浏览器页面2 R ]烘托流程梳理
归纳弥补
web 功用优化
- yahoow b . $ # S35条军规
串联二:
陈词滥调,请你谈一下闭包?
陈词滥调,请你谈一下闭包?
假若你以为此题简略,一两句话就能说完?那当真浮于外表。此题实则一两天都说不完!它能够牵扯出 js 原理的大部分常识。是真实意义上的“母题”。
一图胜万言

- 原创脑图,转载请阐明出处
串联常识点:闭包、效果域、原型链、js承继。
串联回忆:此题并非像上文题“从输入URL到页面加S X c _ E [ b J J载产生了什么?”,后者“串联点”是按答复进程来递进的。而这儿的“串联点”,更多是你中有我,我中有你,前后相互弥补,相互完善。当你领略完的时分,必定会有一种“万物归宗”的感觉。
归并为一五言诗来回忆:h u E Q a F : 5 B
闭包效果域
原型多考虑
承继八大法
根底好好叙
一、闭包
闭D V V l x X } i B包意义
一言以蔽之。
在一个函数内有另外一个函数能够拜访它的内9 + u U b O部变量,并且另外一个函数在外部被调用,这样的D v q X S ! W B f词法环境叫闭包。
- 效果:w A :
- 读取函数内部的变量;(私有变量、不污染大局)
- 让变量始终保存在内存中。
闭包运用
- 最经典试题
for(var i = 0; i < 5; i++){
(function(j){
setTimeout(function(){
cT f I 6 ^ ; ( y |onsole.log(j);
},1000);
})(i);
}
console.log(i);
废物收回机制
- js 废物收回机制:符号铲除和引证计数。
符号铲除简略讲便是变量存储在内存中,当变量进入履行环境的时分,废物收回器会给它加上符号,这个变量离开履行环境,将其符号为“铲除”,不可追寻,不被其他方针引证,或许是两个方针相互引证,不被第三个方针引证,然后由废物收回器收回,开释内存空间。
防抖、节流函数
- 防抖
function debounce(fn, delay) {
var timer; // 维护一个 timO z u ] Z @ 2 m rer
r% 0 W g Oeturni f 1 T l , 0 P $ function () {
var _this = this; // 取debounce履行效果域的this
var args = arguments;
ik t , ! V 8 ^ #f (timer) {
clearTimeout! 8 K y(timer);
}8 C d u
timer = setTimeout(function () {
fn.ap? , d Y 3ply(_this, args); // 用apply指U 6 s 2 + A ( 0 D向调用deboun@ K k 9 )ce的方针,相当于_this.fn(args);
}, delay);
};
}
- 节流Q r d W l y X |
fE y ; $ l h f i Cunction throttle(fn, delay) {
var timer;
return function () {
var _this = this;
var args = arguments;
if (timer) {
return;
}
timer = setTimeout(function () {
fn.apply(_this, args);
timer = null; // 在delay后履行完fn之后清空timer,此刻timer为假,throttle触发能够进入计时器
}, delay)
}
}
二、效果域
大局效果域
- 直接编写在script标签J T u M 0 o n )中的JS代码,都在大局效果域;
- 大局效果域在5 N d { ~页面翻开时创立,在页面封闭时毁掉;
- 在大局效果域中有一U p m = 2 f个大局方针window,它代表的是一个浏览器的窗口,它由浏览器创立咱们能够直接运用;
- 大局效果域中,创立变量都会作为window方针的特色保存;
- 创立的函数都会作为window方针的办法保存;
- 大局效果域中的变量都是大局变量,在页面的任何部分都能够拜访的到s 5 Z ];
咱们能够在操控台直接打印试试看,正如以上所说:

函数效果域(部分效果域)
- 变量在函数q ; ] t内声明,变量归于部分效果域。
- 部分变量:只能在函数内部拜访。
- 部分变量只效果于函数内,所以不同的函数能够运用相同称号的变量。
- 部分变T 9 0 ! s a量在函数开端履行时创立,函数履行完后部分变量会自动毁掉。
块级效果域
块级效果域 : 块级效果域指的便是运用 if () { }; while ( ) { } ……N V k w D Z ?这些句子所构成的句子块 , 并且其间变量有必要运用 let 或 const 声明,确保了外部不能够拜访句子块中的变量。u } u
注:函数效果域和块级效果域没有直接联络。
- const、let、var 差异
- const 声明则不能改动,块级效果域,不允许变量提高。
- let 块级效果域,不允许变量提高。
- var 非块级效果域,允许变量O & t +提高。
效果域链
呈现函数嵌套函数,则就会呈现效果域链 scoz Y 5pe chain。
- 遍历嵌套效果域链的规矩很简略:引擎从其时的履行效, ^ P l M 3果域开端查找变量,假如找不到, 就向上一级持续查找。当抵达最外层的大局效果域时,无论A s L h h x找到仍是没找到,查找进程都会中止。
- 部l & L L q分效果域m t w – _ % J .(如函数效果域)能够拜访到大局效果域中的变量和办法,而大局效果域不K E q 2 . I能拜访部分效果域的变量和办法。
用效果域链来解说闭包:
function outter() {
var private= | l e"I am privatea y h U ` w 1 X";
function show() {
console.log(private);
}b I z * M
// [[scope]]现已确定:[outter上下文的变量方针,大局上下文变量方针]
return2 r h } m show;
}
var ref = outter();
console.log(private); // outter履行完今后,pd H F @ Hrivate不会被毁掉,并且只能被showc [ b G办法所拜访,
//直接拜访它会呈现报错:private is not defined
ref(); // 打印IT ~ I am private
其g N d 0 V ]实,咱们要了解的是函数的声% s &明和调用是分开的,假如不搞清楚这一点,许多根底面试题就简单出错。
- 深究:
Javr 0 v 3 o h 4 } TaScript深入之词法效果域和动态效果域 #3
变量生命周期
一个变量的声明意味着便( n 1 ( k U W _是咱们在内存当中申请了一个空间用来存储。这个内存也便是咱们电脑的运转内存,假如咱们一向的声 c c P 8 V e [明变量,不开释的话。会占用很大的内存。
在 c/M d – 9 9 e 4 . ic++ 当中是需求程序员在合适的当地手动的去开释变量内存,而 javascript 和 javQ j Q s V 0 H 6a 拥有废物收回机制(咱们在上文已阐明)。
js 变量分为两种类型:大局变量和部分变量
- 大局变量F @ 1 B M N z R &的生命周期:从程序开端履行创立,到整个页面封闭时,变量收回。
- 部分变量的. 9 J生命周期:从函数开端调用开端,一向到函数调用完毕。
但有的时分咱们需求让部分变量的生命周_ r E q 1 ] . e期A v 6 Q j长一点,此刻就用到了闭包。
三、原型链
实例与原型
一个原型方针的隐形特色指向结构它的结构函数的显现特色。
当一个方针u b z去查找它的特色,找不到就去找他的结构函数的特色,一向向上找,直到找到 Object()。
判别数据类型
- typeof
- instanceofQ N ;
- constructor
- Object.prototype.toString.call()
new 一个方针
进程:
- 创立一个新方针
- 将d E , t ;结构函数的效果域赋给新方针(因而this指] m n c 2 P K向了这个新方针)
- 履行结构函数中的代码(为这个新方针增加特色)
- 回来新V d 8 (方针
this 指向
this 指向 5 大规矩:
- 假如 new 关键词呈现在被调用函数的前面,那么JavaScript引擎会创立一个新的方针,被调用函数中的this指向的便是这个新创立的函数。
- 假如经过apply、call或许bind的办法触发函数,那么函数中的this指向传入函数的第一个参数。
- 假M ` a r s x )如一个函数是某个G 5 U * ) V ] c :方针的办法,并且方针运用句点符号触发函数,那么this指向的便是该函i b i l 3数作为那个方针的特色的方针,也便是,this指向句点左面的方针
- 假如一个函数作为F| [ G d 8 dFI被调用,意味着这个函数不符合以上恣意一种调用办法,tx 8 Z V u ahis指向大局方针,在浏览器中,便是window。
- 假如呈现上面对条规矩的累加状况,则优先级自1至4递减,this的指向依照优先级最高的规矩判别。
参阅:this指向回忆5大原则
- 箭头函数中的^ T ~ : x ` & this 指向:箭头函数中的this是在界说函数的时分绑定,而不是在履行函数的时分绑定。
更多:JS中的箭头函数与this
bind、call、apply
- call
call()办法接纳的第一个参% u z p 9 2 } ]数和apply()办法接纳的一样,改动的是其余的参数直接传递给函数。换句话说,在运用call()办法时,传递给函数的参数有必要逐一罗列出来。
function s] M ! P wum(num1 , num2){
return num1 + num2;
}
function callSum(num1 , num2){
return sum.call(this , sum1 , suq + @ Cm2);
}
console.log(callSum(10 , 10)); //; @ - % z 20
- apply
apply()办法d . : 6 & b Y接纳两个参数:一个是在其间运转函数的效果域,另一个是参数数组,这儿的参数数组能够是Array~ ? X V + K |的实例,也能够是arguments方针(类数组方针)。
functio} e # J T O ! , ]n sum(num1 , num2){
return num1 +t t ] h num2;
}
function callSum1(num1,num2){
return sum.apply(this,argumZ n & * a L ] . Re! g ` + p M | Ents); // 传入arguments; s B A * m类数组方针
}
function callSum2(num1,num2){
return sum.apply(this,[num1 , num2]); // 传入数组
}
console.log(callSum1(10 , 10)); // 20
console.log(callSum2(10 , 10)); // 20
call和apply的差异在于二者传参的7 q % x L + ? ` L时分,前者是一个一个的传,后者是传数组或类数组arguments
- bind
bind()办法创立一个新的函数9 f $, 当被调用时,将其this关, L k键字设置为供给的值,在调用新函数时,在任何供给之前供给一个给定的参数序列。
手写深浅复制
浅:
function clone(target) {
let cloneTarget = {};
for (const key in target) {
cloneTarget[key] = target[key];
}
return cloneTa s E | F g L Y Trget;
};
深(递归):
function clone(target) {
if (typeof target === 'object') {
let cloneTarget = Array.isArray(target) ? [] : {E = ` :};
for (const key in target) {
cloneTarget[key] = clone(target[key]);
}
return cloneTarget;
} else {
returW E Zn target;
}
};
了解更多,引荐阅览:怎样写出一个惊艳面试官的深2 T k i S复制?
四、js 承继
八种承继办法,具体请看此篇:JavaScrii n o Z k +pt常用八种承继方案。
本瓜不做赘述,可列二三关键必记。
串联三:
请你谈谈 Vue 原理?
请你谈谈 Vue 原理?
本瓜不装了,摊牌了。其实本文的目录结构编写时刻线在 《 Vue(j + : 6 d 7 |v2.6.11)万行r C C & l Q E源7 O : d码生啃,就硬刚[ e : ~ R N!》
这篇文章之P ? + ! m ]前。其时便是由于似懂非懂v z ( Q q,才定下心来“生啃源码”。现在源码看完了,领会确实又不一样了。但由于细节太多,篇幅受限。此处也仅列结构、点出关键、注释链接,以便回忆。
一图胜万言J } ` P v h v

- 原创脑图,转载请阐明出处
串联常识点:Vue初始化和生命周期、虚拟DOM、呼应式原理、组件编译、Vue常用弥补I c u W & B 6 G、Vue全家桶。
串联回忆:编一顺口溜,见笑。
V U E 真简单
初始化 有生命
虚拟 dom 好给力
呼应式 看细心
组件化 咱们利
全家桶 笑嘻嘻
会打包 挣一亿
- 邀咱们来改编Y _ # U B v O
一、init&n V ] c E ]amp;render
挂载和5 m T y e ; $ I初始化
new Vue()产生了什么?
Vue 实践上是一个类,类在 Javascript 中是n C + I ( C s $ n用 Function 来完结的。Vue 只能经过 new 关键字初始化,然后会调用 this._init 办法。
初始化首要完结:兼并装备(mergeOpt} H ! sions),初始化生命周期(initLifecycle),初始化事情中心(initEvents),初始化烘托(initRender),初始化 data、pr# d L H P I , w vops、computed、watcher 等等。
流程图参阅如下:

- 此图在组件编_ / u ` B译环节少了 optimize ,或许由于版别差异。 Vue2.4.4 源码
- 借图,未找到实在出处,保存引q I ` %证阐明坑位。
实例生命周期
生命周期图示,仍是得看官网文档。还记住这句话吗?
下图展示了实例的生命周期。你不需求立马弄了解全部的东西,不过跟着你的不断学习和运用,它的参阅价值会越来越高。
注释版:

引荐:源码解读
关键注释:
- beforeCreate 和 created 函数都是在实– } 6 2 Z I D X例化 Vue 的阶段,在 _init 办法中履行的。从源码中能够看到 beforeCreate 和 created 的钩子调用是在 initState 的前后,initState 的效果是初始化 prop! [ )s、data、methods、watch、computed 等特色。那么明显 beforeCreate 的钩子函数中就不能获取到 props、data 中界说的值,也不能调用 methods 中界说的函数。而 created 钩子函数能够。
Vue.prototype._init = function (options?: Object) {
// ...
initLifec0 o ~ p ~ ] L Dycle(vm)
initEvents(vm)
initRender(vm)
callHook(vm, 'bek 7 #foreCreate') // beforeCreate 钩子
initInjections(vm) // resolve injections before data/props
initState(vm)
initProvide(vm) // resolve provide after data/props
callHook(vm, 'created') // created 钩子
// ...
}
-
在履行 vm._render() 函数烘托 VNode 之前,履行了 beforeMount 钩子函数,在履行完 vm._update() 把 VNode patch 到实在 DOY R } M 后,履行 mountK 6 i } J U A g Eed 钩子。c x B ~ a –(此点重要)
-
beforeUpdate 的履行机遇是在烘托 Watcher 的 befc ; }ore 函数中调用。update 的履行机遇是在 flushSchedulerQueue 函数调用的时分。
-
beforeDestroy 和 di ! u d l T g 9 Festrom B M } Vyed 钩子函数的履行机遇在组件毁掉的阶段。
-
activated 和 d3 C ( V (eactivated 钩子函数是专门为 keep-al2 A D Y 3 o L wivV % =e 组件定制的钩子。# f 2
关键阐明:
- 在 Vue2 中,全部 Vp ~ ? e Q n X rue 的组件的烘托最终都需求 render 办法,无论咱们是用单文件 .vuep h 2 Y b 办法开发e 1 P % g b ^组件,仍是写了 el 或许 templaf 5 8 * u K ste 特色,最终都会转换成 render 办法,用来把实例烘托成一个虚拟 Node(Virtual DOM)。
二、虚拟DOM
Vue 2.0 相比 Vue 1.0 最大的升级便是运用了 Virtual DOM。
vdom
vdom 其实便是一颗 js 方针树,最少包括标签名( tag)、特色(attrs)和子元素方针( children)三个特色。本来对 DOM 节点1 Y i p的操作(浏览器将 DOM 规划的十分复杂)转成了对 js 方针的操作,加快处理速度、提高功用。
VNode 的创立是由 createElement 办法完结的。
欲2 ) m u g 4 u %知原理,引荐阅览:snabbdom
diff & patch
在实H w Z践代码中,会对新旧两棵树进行一个深度的遍历,~ – 4 n % ^每个节点都会有一个符号。每遍历到一个节点就把该节点和新的树进行比照,假如有差异就记载到一个方针中。即用 diff 算法比较差异,然后调用 patch 运用到实在 DOM 上去。patch~ – 5 r | 的进程即一个打补丁的进程。

图片来历
diff 算法是一个交叉比照的进程,大致能够简要概括为:头头比较、尾尾比较、头尾比较、尾头比较。
入O ? [ %门级别 diff 概况引荐看此篇:LINK

图片来n 0 S L ! y ~ U历
留意:render函数回来的是 vdom,patch生成的才是实在DOM。
三、呼应式原理
官方生图,高屋建瓴。

本瓜曾在《简析 vue 的双向绑定原理》这篇文章写过,如今看又是一番心境。
当你把一个一般的 JavaScrip4 V o m . zt 方针传入 Vue 实例作为 data 选Y ~ u H S 项,Vue 将遍历此方针全部的 prop! % q )erty,并运用 Object.definePropertyG G Z O c 把这些 property 全部转为 getter/setter。ObJ A o M O 2ject.defineProperty 是 ES5 中一个无法 shim 的特性,这也便是 Vue 不支撑 IE8 以及更低版别浏览器的原因。
发布订阅者形式(字节考题)
class emit {
}
cosnt eeee = new emit()
eeee.on(] 8 k'aa' , function() { console.log(1)})
eeeeU # d 3 v.on('aa' , function() {console.log(2)})
eeee.emit('aa')
//class e/ . x o )mit{}
// 要求手写发布者-订阅形式
class Subject{
constructor () {
this.observep Z p m j % L zrs =[]
}
add (obg 6 x , U E h gserver) {
this.observers.push(observer)
}
notify () {
this.observers.t 2 *map((item, index) => {
item.update()
})L , .
}
}
class Observer {
constructor (name) {
this.name =m } s / name
}
update () {
console.log("I`m " + this.name)
}
}
var sub = new Subject()
var obs1 = n] I z qewe Q . o Observe. * 3 D s o / ) vr("obs1x } # l n U ?")
var obs2 = news 1 Z D R I _ p Observer("obs2")
sub.add(oI / f u : Z Obs1)
sub.add(obs2)
sub.notify() // I`m obs1 IL , ( $ S W`m obs2
除了“发 8 h A 1 3 M布者订阅形/ O – p X .式”,你还知道哪些 js 规划形式?这儿留个坑,今后再补,东西太多了……
Observe
Observe 的功用便是用来监测数据的改动。它的效果是给方针的特色增加 getter 和 se v G L J n Ntter,用于依靠M C I @ k _搜集和派发更新:
这儿贴一下源! V ^ X码片段,咱能够感触下:
export class ObserP z Mver {
value: any;
dep: Dep;
vmCount: numberM q H 1 e q ` }; // number of vms that has this objY ) 2 f @ V 0 @ Kect as root $data
constructor (value:x Q q j q : , L any) {
this.value =t v o value
this.de) K A 6 ! qp = neV n s fw Dep()
this.vmCount = 0
def(va5 : M # I F $ Vlue, '__ob__', this)
...
}
walk (obj: Object) {
...
}
observeArray (items: Array<any&a / 0 g ~ : c x )gt;) {
..m : A w ~ 5 #.
}
}
有没有觉得和上面提到的“发布订阅者形式”中的相似。Obk $ Q k [server 首要实例化 Dep 方针y ) 2 H P ! & –,接着经过履行 def 函数把本身实例增加到数据方针 value 的 ob 特色上。(def 函数是一个简略的对 Object.definR j . h a ` 9 9eProperty 的封装)。
Dep
Dep 是整个 getter 依靠搜集的中心。

由于 Watcher 是有多个的,所以需0 t 6 U | K – x求用 Dep 搜集改动之后集中办理,再告诉到对应的 Watcher。由此也好了解 Dep 是依靠l H于 Watcher 的。
贴源码片段,感触一下:
export defaul7 ; j h M + 8t class Dep {
static target: ?Watcher;
iE F ? l *d: number;
subs: Array<Watcher>;
cons5 g M D ) y o m structor () {
this.id = uid++
this.subs = []
}
addSub (suX D Db: Watcher) {
th= $ A -is.subs.push(sub)
}
removeSub (sub: Watcher) {
remove(thY r . + S L | a tis.subs, sub)
}
depend () {
if (Dep.target) {
Dep.target.addDep(this)
}
}v [ ! .
notify () {
// stabilize the subscriber li~ ^ { $ A , f lst first
...
}
Watcher
贴源码片段,感触一二:
export defaula % U 3 s 4t class Watcher {
vm: Component;
expression: string;
cb: Function;
id: number;
deep: boolean;
user: boolean;
computed: boolean;
sync: boolean;
dirty: boolean;
active: boolean;
dep: Dep;
deps: Array<Dep&gG P h y ? Jt;;
newDeps: Array<Dep>;
depIds: SimpleSet;
newDepIds: SimpleSet;
beP K G U ? c { sfore: ?Function;
get? d I H Q ^ 4 :ter: Function;
value8 K z U: any;
constructort 0 ; z % , j (
vm: Component,
expOrFn: string | Function,
cb: Functionk Y R Q s A,
optionu ( K Xs?: ?Object,
isRenderWatcher?: boolean
) {
this.vm = vm
if (isR@ x g DenderWatcher) {
vm._watcher = thiO V n = A e ; & as
}
vm: | ( Z . 3 c + .._waR ` U + A + ^tchers.push(this)
// options
...
// parse expression for getter
...
}
get () {
pushTarget(this)a P s R x 1 P
..W u + q ( K 6.
}
addDep (dep: Dep)b S s ` c {
const id = de} 2 s t Wp.id
...
}
cleanupDeps () {
...
}
// ...
}
Watcher 会告诉视图的更新 re-render。
常见视图更新场景:
- 数据变 → 运用数据的视图变(对应:负责敦促视图更新的rP ! , _ E s F ! /ender-watcher)
- 数据变 → 运用数据的核u c L – + K算特色变 → 运用核算特色的视图变(对应:履行敦促核算特色更新的computed-watcher)
- 数据变 → 开发者自动注册的watc K /ch回调函数履行(对应:用户注册的一般watcher(watch-api或watc8 8 I $h特色))
四、组件编译
组件的思维也是 Vue 中心,将组件编译为 vdom ,则也是一重难点!

你能够发现在 Vue 这一节有许多引证的图,其实它们有的相似,更多的是侧关键不同,主张都可依照流程图了解了解,做到融会贯通。
组件
官方示例:
// 界说一个名为 button-c 9 G X { o R Pounter 的新组件
Vue.component('button-counte, t #r', {
data: function () {
return {
count: 0
}
},
template: '<button v-on:click="coun? g @ Vt++">You clicked me {{ count }} times.</button>'
})
<dx 0 B tiv id="componentsb s T-demo">
<button-counter></button-counter>
</div>
new Vue({ el: '#components-demo' })
组件还触及:组件之间的p Y _ [ b n u I c通讯_ – r 7 v、插槽、动态组件等内容。后续再表(OS:
这是自己给自己挖了个多大的A D K U | h 4坑)。
parse
编译进程首要便是对X . ;模板做解析,生成 . h ! H AST,它是一种笼统语法树,是对源代码的笼统语法结构的树状表现办法。在许多编译技能中,如 babel 编译 ES6 的代码都会先生成 AST。这个进程会用到i Z e很多的正则表达式对字符串解析,源码很难读。
可是咱们需求知道的是 start、end、comment、chars 四大函数。
对于一般标签的处理流程大致:
- 辨认开端标签,生成匹配结构match。
- 处理attrs,将数组处理成 {name:’xxx’,value:’xxx’}
- 生成astElement,处理for,if和once的标签。
- 辨认完毕标签,将没有闭合标签的元素一起处理。
- 树立父子联络,最终再对astElement7 K ^ | Y m d –做全部跟Vue 特色相关对处理。slot、component等等。
参阅阅览:Vue parse之 从template到astElement 源码详解
optimize
当咱们的模板 template 经过 parse 进程后,会输出生成 AST 树,那么接下来咱们需求对这颗树做优化 —— optimize。
optimize 中最重要的是符号静态根(markStaticRoots )、静态节点(markStatic )。假如是静态节点则它们生成的DOM永远不需求改动,这让模板的更新更搞笑(不变的节点不必更新)。
问题:为什么子节点的元素类型是静态文本类型,就会y / K ?给 optimize 进程加k 0 I大本钱6 X s . & g ~ #呢?
首要来剖析一下,之所以在 optimize 进程中做这个静态_ B t v p根节点的优化,意图是什么,本钱是什么} o x g r v *?意图:在 patch 进程中,削减不必要的比对进程,加快更新。
本钱:a. 需求维护静态模板的存储方针。b. 多[ = e m –层render函数调用。
引荐阅览
codegen
编译的最终一步便是把优化后的 AST 树转换成可履行的代码,即在 codegen 环节。
首要进程(} 7 a n | O调用函数):
- generate
- genIf
- genFor
- genData &aI , b bmp; genChia A * r r ~ [ldren
此节考的不多] y 2 7,仅做了解。了解更多V u 7 * p,得h m h看源码。
五、常用弥补
keep-alive(常考)
keepalive 是 Vue 内置的一个组件,能够使被包括的组件保存状况,或避免重新烘托 。也便是所谓的组件缓存。
v-if、v-shT ? ;ow、v-for5 K ]
三个高频子问题:
- v-if、v-show 差异?
答:v-if 相当于 display; v-show$ b = 相当于 visibility; 前者会操控是否创立,后者仅操控是否隐藏显现。
- v-if、v-for 为什么不能放一起用?
答:由于 v-for 优先级比 vF h } M u-if 高,所以在每次重新烘托的时分会先遍历整个列表,再进行 if 判别是否展示,耗费功用。
- v-for 中能用 index 作 key 吗?
答:key 是 diff 算法中用来比照的,用 index 作为 key 并未仅有辨认,当刺进元素时,key 也会改动。index 作为 key,只适用于不依靠子组件状况或临时 DOM 状况 (例如:表单输入值) 的列表烘托输出(官网阐明)。
本瓜这儿不做细答,想了解t } } 5 | C更多请自行处理。
自界说指令
Vue 中的混入(Minxin)、自9 p y Z J D界说s 9 E 6 ( S i指令(directive)、过滤器(filter)有共通之处,在注册的时分,需求平衡部分注册和大局注册的好坏。
tranK F F 8sitb 1 Yion
本瓜读源码的进程中,发现源码中有较大的篇幅在描述关于transition。在官方文档中,transitioW D K X g n 也是作为独立的重要一n 7 * j S节来阐明。进入/离开 & 列表过渡,Vue 动画&过渡,是简单忽视的点$ ; : F 。
六、全家桶
自从用上了 V t S & Nue 全家桶,腿也不疼了,腰也不酸了。咦,一口气写五` ` * T f X L 9 n个页面,妈妈再也不必担心我的学习了。(好像有点串p Q R广告了…..F + 8 R Q Y ^ u M.)N x * ( u
Vue-Router
官方的+ = 路由办理器
分为两种形式:hash 和 history
- 默许= v U ) j hash 形式,经过加锚点的办法
- history 运用 history.pushState APQ ( E e % u G [ xI完结
原生:
HTML5引入了 history.pus7 b u N GhState() 和 history.repla9 D m /ceState() 办法,它Z r f A } @们别离能够增加和修正历史记载条目。这些办E 3 Q @ #法一般与window.onpopstate 合作运用。概况链接
Vuex
官方状况办理
由以下几部分中心组成:
- state:数据状况;
- mutations:更改状况(核算状况)A 4 + L } K ^;
- getters:将state中的某个状况进L D F p m行过滤然后获i f D 1 e ] A取新的状况;
- actions:履行多个mu= k P `tationb m T 7 M – X N,它能够E ~ [ –进行异步操作(async );
- modules:把状况和办理规矩分类来装,让目录结构更明晰;
VueCLI
官方脚b I v手架
- VueCLI4中很重要的是 vue.config.js 这个文件的装备。
VuePre? – F q | W Pss
静态网站生成器
- 选用 V{ . X h Vue + webpack,u u x能够在 Markdown 中运用 Vue 组件,页面简练大方,与 Vue 官网风格一致。
NuxtJS
服务端烘托
七、webpack
只需你做前端有两年经验左右,那一样就得要求自己把握一款打包工具了。
webpack 原理
官方解说:
webpack 是一个现代 J/ [ CavaScript 运用程序的静态模块打包工具。当 webpack 处理运用程序时,它会在内部构建一个 依靠图(dependency graph),此依靠图会映射a @ X项目所需的每个模块,并生成一个或多个_bundle_。
中心概念:F w x q i ^ / a A
- Entry:进口,Webpack) U U 履行构建的第一步将从 En} % g {try 开端,可笼统成输入。
- Module:模块,在 Webpack 里全部皆模块,一个模块对应着一个文件。N j { { | %Webpack 会从装备的 Entry 开端递归找出全部依靠的模块。
- Chunk:代码块,一个 Chunk 由多个模块组合而成,用于代码兼并与切割。
- Loader:模块转换器,用于把模块原内容依照需求转换成新内容。
- Plugin:扩展插件,Y 0 ; f 1 3 x在 Webpack 构建流程中的特定机遇会广播出对应的事情,插件能够监听这些事情的产生,在特定机遇做对应的事情。
功用:
代码转换、文件优化、代码切割、模块兼并、自动改写、代Y g d H h z码校验、自动发布。
优化打包速度
- 搭载 webpack-parallel-6 j auglify-plugin 插件,加快“紧缩JSH ! E g 7 V=>编译成 AST=>复原JS”的进程。
- 运用 HappyK Q 5 i d | q lPack 提高 loader 解析速度。
- 运用 DLLPlugin 和 DLLReferencePlugin 插件,提早打包。
- tree-shaking 用来消除无用模块。
AMD、CMD
前端模块化有四种标准:CommonJS、AMD、CMD、ES6。
- AY A = } dMD(异步模块界说)
- CMD(通用模块界说)
AMD(异步模块界说) | CMD(通用模块界说) |
---|---|
速度快 | 功用较差 |
会浪费资源 | 只需真实需求才加载依靠 |
预先加载全部的依靠,直到运用的时分才履行 | 直到a b – 4 j 5 m 0 $运用的{ ~ | X l v时分才界说依靠 |
-
Node.js是commonJS标准的首要实践者:module、module.exports(exports)、require、global。
-
ES6 在语言标准的层面上,完结了模块功用,首要由两个指令构成:export和import。export指令用于规矩模块的对外接口,import指令用于输入其他模块供给的功用。
问:比较 import 和 require 的差异?
import | require |
---|---|
ES6标准中的模块; m W化处理方案 | 是node中遵循CommonJS标准的模块化处理方案 |
不支撑动态引o * ! X 8 l /入 | 支撑动态引入 |
是关键词 | 不是关键词 |
编译时加载,有必要放在模块顶部 | 运| K Q R $ 4 l / X转时加载,理论上来说放在哪里都能够 |
功用较好 | 功用较差 |
实时绑定办法,即导入和导出的值都指向同一个内存地 | 导出时是值复制9 c @ / O l w b,就算导出的值改动了,导入的值也不会改动 |
会编译成require/exports来履行 | – |
更多:前端模块化:CommonJS,AMD,CMD,ES5 f 6 6 F c (6
完结plugin插件(腾讯WXG考点)
- 创立 plugins/demo-plugin.js 文件;
- 传递参数 OptionM j @ O O Y e Q ms;
- 经过 Comj A * P s 1 !pilation 写入文件;
- 办理 War4 a { g & – H f wnings 和 Errors
从零完结一个D # & = 3 B @ Webpack Plugin
串联四:
你最喜欢什么算法?
你最喜欢什么算法?
其实本瓜想答复:我最喜欢减法!由于幸福生活 _ ^需求用减法。
算法这一个 part 也已久远,既然逃不掉,那就正面挑} p d J m战它!其实也没那么难。
一图胜万言

- 原创脑图,转载请阐明出处
串联常识点:数据结构、根底算法、排序算法、进阶算法。
串联回忆:
算法算法我不怕
数据结构打趴下
遍历排序我最溜
指针动态贪心刷
一i C ` F、数据结构
行列
先入先出。
栈
先入后出。
堆
堆一般是一个能够被看s & U v f b 1 ) u做一棵树的数组方针。? + V h z [ o d
堆总是满意下列性质:
- 堆中某个节点的值总是不大于或不小于其父节点的值;
- 堆总是一棵彻底二叉树。
- 彻6 % o _ d底2 B f ( / F 5 q二叉树:在一颗二叉树中,若除最终一层外的其余层都是满的,并且最终i V f T L z d一层要么是满的,要么在右边缺少接连若干节点,则此( # L I { D s ^二叉树为彻底二叉树(Complete Binary Tree)—— wiki。
(本瓜曾被拷问过这个点,大厂便是会考《数据结构》,别躲避,出来混迟早& & o M是要还的)。
链表
- 循环列表(考点+ h 3 T % n 5)
// 循环链表
fu4 z 0 / [ Anction Node(element){
this.element = element;
this.prev = null;
this.next = null;
}
funcA a t ` | 6tion display(){
var current = this.headt k K 5 %;
//查看头节点当循环到头节点时退出循环
whi8 % le(!(current.next == null) &aG C a ^ Z } C ump;& !(current.next.element=='head')_ X C * q z R){
print(c0 k P , ! # @ _urrent.next.element);
current = curV u | y w u 3 Krent.next;
}
}b $ M , ( {
function Llist(){
this.head = new Node('head');
this.head.next = this.head;
this.find = find;
th: ) l ^ qis.] U p 7 5 )ij 2 Dnsert = insert;
this.display = displayu 8 7 d [ ( a H g;
this.findPrevious = findPrevious;
this.remove = remove;
}
哈希
散列函数(英语:Hash funct~ B /ion)又称散列算法、哈希函数。以 Key:Value 的办法存储数据。
哈希表最大的特色是能够快速定位到要查找的数据,查询的时刻复杂度接近O(1)。本瓜主张咱们能够把这儿全部的数据结构的“增修改查”操作的时刻复杂度都理一下,也是会被考的。
时刻复杂度、空间复杂度
简略了解:
- 循环的次数写成 n 的表达式H ] ! [ q * 8,便是时刻复杂度。
- 申请的变量K C S Y m / _ u y数量写成 nc @ G 的表达式,便是空间; ! d ^ j复杂度。
时刻复杂度更多重要一点m d c ) n 8,常见的时刻复杂度:O(1){ | # / ` u、O(n)、O(logn)、O(n2)。本瓜小TIP:面试/书面考试假如不知道怎样算,就在这儿面猜吧。实在不可就答:O* C J 1 L J l #(n) ~ O(n2) 之间,大概率不会错。
树的遍历(广度、深度)
广= b m $ 9 { /度优先遍历(BFS):
需求用到行列(QueuB G / w s Ee)来存储节点方针,行列的特色便是先进先出。示例
深度优先遍历(DFS):
- 前序(根结点 -> 左子树 -> 右子树)
- 中序(左子树 -> 根结点 -> 右子树)
- 后序(左子树 -> 右子树 -> 根结点)
二、根底算法
递归思维
- 闻名的斐波那契数列,你要知道!% S Q ` $ 5 4
function re _ _ ? % 3 g ^sult(){
if(n==1||n==2){
return 1
}
return re] S g F ) 9slt(n-2)+result(n-1)
}
- 函数柯里化,你也要知道!
函数柯里化:是把承受多个参数的函数变换成承受一个单一参数(开始函数的第一个参数)的函数,并且N W S ! q B回来承受余下的参数并且回来成果的新函数的技能。—— wiki
// 一般办法
var add1 = function(a, b, c){
return a + b + c* Q f G K;
}
// 柯里化
var add2 = ft r e * I _ R %unc* i 8 r . %tion(a) {
return function(b) {
return function(c) {
return a + b + c;
}
}
}
// demo
var foo = function(x) {
return function(y) {
return x + y
}
}
fo& k Y w P W z Ro(3)(4) // 7
这样处理参数,能够直接追加,而不需求初始传参就写彻底D ; a 1 4 y。这儿仅T } L E s ~仅浅谈$ u ~,更多请自行探索。
二分法
要求手写二分法,实在不可,能默写也能够啊!
// 二分法:先排序,再找方针
function binary_search(arr,target) { ; ~ C
let min=0
let max=arr.len] o L q 5 bgth-1
whi& Y m X $ b C 6le(min<=max){
let mid=Math.ceil((min+max)/2)
if(arr[mid]==targef ; 9 6t){
return mid
}else if(arr[mid]>target){
max=mid-1
}else if(arr[mid]<target){
min=mid+1
}
}, r 0
return "null"
}
console.lA r Kog(binary_search([1,5,7,19,88],19))//3
三、排序算法
排序是比较常用也比较重要的一块,此处并未全列出。仅强调快排和冒泡,会用双循环也行啊。
快速排序
//F O | 快排:选取基准,比基准大的放右边,比基准小的放左面,然后B ^两边用递归
function quickSort(arr, i, j) {
if(i < j) {
let left = i;
let right = j;
let pivot = arr[left];
while(i < j) {
while(arr[5 ( Bj] >= pivot && i < j) { // 从后往前找比基准小的数
j--;
}
if(i < j) {
arr[i++] = arr[j];
}
while(arr[i] <= pivot && i < j) { // 早年往后找比基准大的数
i++;
}
if(i < j) {
arr[j--] = arr[i];
}
}
arr[i] = pivot;
quickSort(arr, left, i-1);
quickSort(arr, i+1, right);
return arr;
}
}
冒泡排序
// 冒c W E { [ x j泡:双层循环
var arr=[10,20,50,100,40,200];
for(var i=0;i<arr.length-1;i++){
for(var j=0;j<ar: G V H c u ~ vr.length-1-i;j++){
if(arr[j]>arr[j+1]){
var temp=arr[j]
arr[j]=arr[j+1]
arr[j+1]=temp
}
}
}
console.log(arr)
四、进阶算法
双指针
看到“有序”和u n E 8 S K k“数组a f E ~ . P _”。马上把双指针法调度进你的大脑内存。一般双指针走不通,马上想对撞指针!
示例:兼并两个有序数组(双指针7 ? K解法)
示例: 输入:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6], n = 3
输出: [1,2,2,3,5,6]f C ^ ~ % $ Q
/**
* @param {number[]} nums1
* @param {number} m
* @param {number[]} nums2
* @param {l 6 ; 6 2 ] knum[ ! N c L A wber} n
* @return {void} Do not return anything/ Y c K }, modify nums1 i@ k h c . s 1 9 pn-place instead.
*/
const merge = function(nums1, m, nums2,z 8 d ( n) {
// 初始化两个指针的指向,初始化 nums1 尾部^ R 3 i n ! k 3索引k
let i = m - 1, j = n - 1, k = m + n - 1
// 当两个数组都没遍历完时,指针同步移动
while(i >= 0 &amm # ] 3 j j ; o Gp;& j >= 0) {
// 取较r ! /大的值,从结尾往前填补
if(nums1[i] >= nums2[j]) {
nums1[k] = nums1[i]
i--
k--
} else {
nums1[k] = nums2[j]
j--
k--
}
}
// nums2 留下的状况,特别处理一下
while(j>=0) {
nums1[k] = nums2[j]
k--
j-& = F L A E m = 4-
}
};
高档!
动态规划
动态规X V k B 8 , o划的思维便是把一个大b i a x Q *的问题进行拆分,细分成一个个小s C 的子问题,且能够从这些小的子问题的解当中推导出原问题的解。
一起需求满意以下两个重要性质才干进行动态规划:
- 最优子结构性
- 子问题重叠性质
动态规划实例:斐波拉契数列(上文有提到)
斐波拉契数列:选用递归,尽管代码很简练,可是明显跟着次数的增加` ( J V,导致递归树增加的十分庞大,耗时较久。
用动态规划完结斐波拉契数列,代码如下
function feiBoLaQie(n) {
//创立一个数组,用于寄存斐波拉契数组的数值
let val = [];
//将数组初始化,将数组的每一项都置为0
for(let i =0 ;i<=n;i++){O 2 n 6 - [ | z o
val[i] = 0;
}
if (n==1 || n==2){
return 1;
} elM 1 H [ i | 1se{
val( Y , p 9 V #[1] = 1;
val[2] = 2;
for (7 + .let j =3; j<=n;j++){H g = R { C w
val[j] = val[j: E : 0 e-1] + val[j-2];
}
}
r@ , ? 6 ? g D 7 %eturn val[n-1];
}
console.log(feiBoLaQie(z C 40));//102334155
经过数组 v1 J o Q 2 Bal 中保存了中间成果, 假如要核算的斐波那契数是 1 或许 2k ? A V M q p !, 那么 if 句子会回来 1。 不然,数值 1 和 2 将被保存在 val 数组中 1 和 2 的方位。
循环将会从6 I L V # 3 + 3 到输入的参数之间进行遍历, 将! S +数组的每个元素赋值为前两个元素之和, 循环完毕, 数组的最终一个元素值即为最终核算得到的斐波那契数值, 这个数值也将作为函数的回来值。
动态规划处理速度更快。
- 参阅阅览
- 更多动态规划示例
贪心算法
贪心算法遵循一种近似处o L U 2 Q Q ^ I理问题的技能,期盼经过每个阶段的B 6 f E ?部分最优选择(其时最好的解),然后达到大局的最优(大局最优解)。
注:贪心得到成果是一个能够承受的解,Y t X x ? O I不必定总是得到最优的解。
示例:最少硬币找零问题
是给出要找零的钱数,以及能够用硬= ~ ^ G币的额度P { 1 0 ]数量,找出有多少种找零办法。 如:美国面额硬币有:1,5,10,25 咱们给36美分的零钱,看能得怎样的成果?
function MinCoinChange(coiS ) J , f Xns@ X ^){~ M X
var coins = coins;
var cache = {};
this.makeChange = function(amount){
var change = [], total = 0;
for(var i = coins.length; i >= 0; i: 9 h D--){
var coin = coins[i];
while(total + co, H 3 2 g Z v Hin <= amoC d o q Lunt){
chang/ W q ? 1 qe.push(coin);
total += coin;
}
}
return chi Z ~ & ~ . Eange;
}
}
var minCoinChange = new MinCoinChange([1, 5, 10,t S S 25]);
minCoinChange.makeChange(36);
//[25, 10, 1] 即一个25美分、一个10美分、一个1美分
串联五:
web 安全你知道那些?
web 安全你知道那些?
一图胜万言

- 原创脑图,转载请阐明出处
串联常识点:跨域、XSS(跨站脚本进犯)、CRFS(跨站恳求假造)、SQL 注入、DNS 绑架、HTTP 绑架。
串联回忆:三跨两绑架一注入
一、6 q 2 S i ? f跨域
跨域界说
当一个恳求url的协议、域名、端口三者之间恣意一个与其时页面url不同即为跨域。
跨域约束 是浏览器的$ ] . N )一种维护机制,若跨域,则:
- 无法读取非同源网页的 Cookie、LocalSto~ v – ] A n 5 7rage 和 IndexedDB。
- 无法触摸非同源网页的 DOM。
- 无法向非同源地址发送 AJAX 恳求
跨域处理
跨域处理:
- JSONP;
- CORS(跨域资源共享);
// 一般跨域恳求:只需服务器端设置 Access-Control-Allow-Origin。
// 带cookie跨域恳求:前后端都需求进行设置。
// 如前端在 axios 中设置
axios.defaults.withCredentials = true
- vue项目 设置w e M + proxy 代理;
- nginx 代理;
- 设置document.domain处理$ n 7 I R y ! –无法读取非同源网~ T W `页的 Cookie问题;
- 跨文档通讯 API:window.postMessage();
二、XSST : w x B
XSS 原理
XSS的4 E I : # !原理是WEB运用程4 ) / s /序混淆了用户提交的数据和n A P v E K p 1 %JS脚本的代码鸿沟,导致浏览器把用户的输+ ? J @ ` ` / s L入当成了JS代码来履行。– 5 ] Y x hXSS的进犯方针是浏览器一端的一般用户。
示例:
<input type="% 3 I b K w ntext" value="<%& c N v Y : q M= getParameter("keywo` c Mrd") %&7 . igt;">
<button# U P h s f M D>查找</button>
<div>
您查找的关键词是:<%= getParameter("keyword") %>
</d; s a 5 ( : D h 2iv>
当浏览器恳求
http://xxx/search?keyword="><script>9 ( ] v , ? P;alert('XSS');</script>
歹意代码,就会其履行
反射型 XSS
存储型 XS: I [ c KS 的进犯进程:
- 进犯者将歹意代码提交到方针网站的数据库中。
- 用户翻开方针网站时,网站服务端将歹意代码从数据库取出,拼接在 HTML 中回来给浏览器。
- 用户浏览器接纳到呼应后解析履行,混在其间的l t T Y歹意b ) P c b r J o代码也被履行。
- 歹意代码盗取用户数据并发送到进犯者的网站,或许假充用户的行为,调用方针网站接口履行进犯者指定的操作。
这种进犯常见于带有用户保存数据的网站功用,如论坛发帖、商品谈论、用户私信. 0 #等。
存储型 XSS
反射型 XSS 的进犯进程:
- 进犯者结构出6 S c } L r E #特别的 URj f % –L,其间包括歹意代码。
- 用户翻开带有歹意代码的 URL 时,网站服务端将歹意代码从 URL 中取出,拼接在 HTML 中回来给浏览器。
- 用户浏览器接纳到呼应后解析履行,混在其间的歹意代码也被履行。
- 歹意代码E j 0 E O # r B X盗取用户数` Q i D据并发送到进犯者的网站,或许假充用户的行为,调用方针网站接口履行进犯者指定的操作。
反射型 XSS 跟存储型 XSS 的差异是:存储型 XSS1 6 6 的歹意代码存在数据库里,反| : H射型 XSS 的歹意代码存在 URL 里。
DOM型 X: x hSS
DOM 型 XSS 的进犯进程:
- 进犯者结构出特别的 URL,其间包括歹意代码。
- 用户翻开带有歹意代码的s 0 R H W D URL。
- 用户浏览器接纳到呼应后解析履行,前端 JavaScript 取出 URL 中的歹意代码并履行。
- 歹意代码盗取用户数据并发送到进犯者的网站,或许假充用户的行为,调用方针网站接口履行进犯者指定的操作。
DOM 型 Xp 1 V 9 F iSS 跟前两种 XSS 的差异:DOM 型 XSS 进犯中,取出和履行歹意代码由浏览器端完结,归3 $ I ( v L g S于前端 JavaScript 本身的安全漏洞,而其他两种 XSST f O 都归于服务端的安全漏洞。
XSS 防护
- 输入过滤,不要信任任何客户端的输入;
- 对 HTML 做充沛转义;
- 设0 0 f 9 , ~ %置 HTTP-only:制止 JavaScript 读取某些敏感 CooX U e g | Ckie,进犯者完结 XSS 注入后也无法盗取此 Cookie。
- 验证码:避免脚本假充用户提交危险操作。
- 慎重运用:.innerHTML、.outerHTMLF w 4 V E j c、document.write();
三、CSRF
CSRF 原理
跨站( | 1 s X x W Y恳求假造:进犯者诱导受害者进入第三方网站,在第三方网站中,向被进犯网站发送: : /跨站恳求。运用受害者在被进犯网站现已获取的注册凭据,绕过后台的用户验证,达到假充用户对被进犯的网站履行某项操作的意图。
曾在 09 年产生了闻名的“谷歌邮箱盗取”事情,运用的便是 “CSRF”。
首要流程:
- 受害者登u ? D N录a.com,并保存w # j L # i I j D了登录凭据(Cookie)。
- 进犯者引诱受害者拜访了b.com。
- b.com 向 a.com 发送了一个恳求:a.com/act=xx。浏览D ~ a O h W q p器会默许带着a.com的Cookie。
- a.com接纳到恳求后,对恳求进行验证,并承认是受害者的凭据,误以为是受害者自己发送的恳求。
- a.c– 9 {om以受害者的名义履行了act=xx。
- 进犯完结,进犯者在受害者不知情的状况下,假充受@ w w害者,让a.com履行了自己界说的操作。
注:进犯者无法直接盗取到用户的信息(Cookie,Header,网站内容等),仅仅是冒用 Cookie 中的信息。
这告诉咱们冲浪的时分不能随意点链接,是有危险哒。
CSRF 防护
防护战略:
- 自动防护战略:c H 8同源检测(Origin 和 Referer 验证)。
- 自动防护办法:Token验证 或许 双重Cookie验证 以及合作SI 8 # & h % e , {amea % = f T % ! Tsip R ` W % 7te Cookie。
- 确保页面的幂等性,后端接口不要在GET页面中做用户操作。
四、SQL 注入
SQL 注入原理
Sql 注入进犯是经过将歹意的P | / f X Sq w A ]l 查询V & : G r或增加句子刺进到运用的输入参数中,再在后台 Sql 服务7 f 2器上解析履行进行的进犯,它现在黑客对数据库进行进犯的最常用手段之一。
SQL 注入防护
防护:用sql句子预编译和绑定变量,是防护sql注入的最佳办法。还能够经过严厉查看参数的数据类型的办法来防护。
五、DNn 9 9 +S 绑架
DNS 绑架原理
DNS绑架又称域名绑架,是指在绑架的网络g f V G 2 H (规模内阻拦域名解析的恳求,剖析恳求的域名,把查看规模以外的恳求放行,不然回来假的IP地址或许什么都不做使恳求失去呼应,其效果便是对特定的网络不能拜访或拜访的是假网址。其实实质便是对DNS解析服务器做手脚
DNS 绑架防护r Y a
处理办法:
DNS的绑架进程是经过进% c n & @ , m犯运营商的解析服务器来达到o * z意图。咱们能够不必运| = c ?营商的DNS解析而运用自己的解析服务器或i E h e D %许是提早在自己的App中将解析好的域名以IP的办法发出去Y 1 $ 1 I + O i 5就能够绕过运营商DNS解析,这样一g ) Y来也避免了DNS绑架的问题。
六、HTTP 绑架
HTTP 绑架原理
在运营: * 4 ~商的路由器节点上,设置协议检测,一旦发现是HTTP恳求,并且是html类型恳求,则阻拦进行歹意处理。
常见] G – h , B有7 @ E g ( E Q d两种:
- 相似DNS绑架回来302让用户浏览器跳转到另外的地址。(钓鱼网站便是这么干)
- 在服务器回来的HTML数据中刺进js或dom节点(广告)。(常见)
HTTP 绑架防护
防护办法:
- 运用HTTPS;
- 运用制止S . H ( ?转码申明;, F 6 3 L
- 在开发z D F _ @ f b _的8 R 2 s D @ g网页中加入3 X % 3 2 U v _ D代码过滤:用 js 查看全部的外链是否归于白名单;
- 联络运营商;
这一 part 更多的是概念上的东西,不求彻底记住,可是也要大致上能说一下。咱老话说的好:) v c r + h ( 7知之为知之 不知为不知,面试官在非关键性的问题上是不做严厉要求的,千万别满嘴跑火车或许直接说不知道,这是两个极点,都不可取。
小结
明显@ 2 | 3 ? * *,前端面试“串联”问题不只限制以上,本瓜会持续依照这个“串联联想”的思路去收拾,不断去打破体系、构成体系(自己给自己挖的天坑呐)。等待在这个反复的进程中找寻真理的痕迹!u # H D ; H
假如你对此文A ` *有更多主意(持续完善中),或是想与本瓜同行,能够加If6 ^ +uc8 * * I K 9 b w ~kinghigh,等待更多沟通 ~
我是掘金安东尼,一j T 9 } d H个会持续输出的个人站长。
评论(0)