对「宏观视角下的浏览器」内容的补充
1、什么是 XSS 攻击
【】XSS 攻击指的是跨站脚本攻击,是一种代码注入攻击。攻击者通过在网站注入恶意脚本,使之在用户的浏览器上运行,从而盗取用户的信息如 cookie 等。本质是因为网站没有对恶意代码进行过滤,与正常的代码混合在一起了,浏览器没有办法分辨哪些脚本是可信的,从而导致了恶意代码的执行
【】XSS 可以分为存储型、反射型和 DOM 型
2、如何防御 XSS 攻击
【】可以从浏览器的执行来进行预防,一种是使用纯前端的方式,不用服务器端拼接后返回(不使用服务端渲染)。另一种是对需要插入到 HTML 中的代码做好充分的转义
【】使用 CSP (内容安全策略),CSP 的本质是建立一个白名单,告诉浏览器哪些外部资源可以加载和执行,从而防止恶意代码的注入攻击
【】对一些敏感信息进行保护,比如 cookie 使用 http-only,使得脚本无法获取。也可以使用验证码,避免脚本伪装成用户执行一些操作
3、什么是 CSRF 攻击
【】指的是跨站请求伪造攻击,攻击者诱导用户进入一个第三方网站,然后该网站向被攻击网站发送跨站请求。如果用户在被攻击网站中保存了登录状态,那么攻击者就可以利用这个登录状态,绕过后台的用户验证,冒充用户向服务器执行一些操作。本质是利用 cookie 会在同源请求中携带发送给服务器的特点,以此来实现用户的冒充
【】三种类型的攻击:GET 类型的 CSRF 攻击、POST 类型的 CSRF 攻击、链接类型的 CSRF 攻击
4、如何防御 CSRF 攻击
【】进行同源检测:服务器根据 http 请求头中 origin 或者 referer 信息来判断请求是否为允许访问的站点,从而对请求进行过滤
【】使用 CSRF Token 进行验证:服务器向用户返回一个随机数 Token ,当网站再次发起请求时,在请求参数中加入服务器端返回的 token ,然后服务器对这个 token 进行验证
【】对 Cookie 进行双重验证
【】在设置 cookie 属性的时候设置 Samesite ,限制 cookie 不能作为被第三方使用
5、SQL 注入攻击与防范、点击劫持
【】SQL 注入概念:就是通过把SQL命令插入到Web表单、页面请求的查询字符串里面提交到服务器,最终达到欺骗服务器执行恶意的SQL命令
【】防范:不要信任用户的输入,要对用户的输入进行校验
【】点击劫持:是一种视觉欺骗的攻击手段。攻击者将需要攻击的网站通过 iframe 嵌套的方式嵌入自己的网页中,并将 iframe 设置为透明,在页面中透出一个按钮诱导用户点击
5、网络劫持有哪几种
【】DNS 劫持: (输⼊京东被强制跳转到淘宝这就属于dns劫持),方法为DNS强制解析、302跳转
【】HTTP 劫持:(访问⾕歌但是⼀直有贪玩蓝⽉的⼴告),由于http明⽂传输,运营商会修改你的http响应内容(即加⼴告)
6、浏览器渲染进程的线程有哪些
【】GUI渲染线程: 负责渲染浏览器页面,解析HTML、CSS,构建DOM树、构建CSSOM树、构建渲染树和绘制页面;当界面需要重绘或由于某种操作引发回流时,该线程就会执行
【】JS引擎线程: JS引擎线程也称为JS内核,负责处理Javascript脚本程序,解析Javascript脚本,运行代码;JS引擎线程一直等待着任务队列中任务的到来,然后加以处理,一个Tab页中无论什么时候都只有一个JS引擎线程在运行JS程序
- GUI渲染线程与JS引擎线程的互斥关系,所以如果JS执行的时间过长,会造成页面的渲染不连贯,导致页面渲染加载阻塞
【】事件触发线程
【】定时器触发进程
【】异步http请求线程:XMLHttpRequest连接后通过浏览器新开一个线程请求
7、对 Service Worker 的理解
【】是运行在浏览器背后的独立线程,一般可以用来实现缓存功能。使用 Service Worker的话,传输协议必须为 HTTPS。因为 Service Worker 中涉及到请求拦截,所以必须使用 HTTPS 协议来保障安全
【】实现缓存功能一般分为三个步骤:首先需要先注册 Service Worker,然后监听到 install 事件以后就可以缓存需要的文件,那么在下次用户访问的时候就可以通过拦截请求的方式查询是否存在缓存,存在缓存的话就可以直接读取缓存文件,否则就去请求数据
8、浏览器缓存的全过程
【】浏览器第一次加载资源,服务器返回 200,浏览器从服务器下载资源文件,并缓存资源文件与 response header,以供下次加载时对比使用
【】下一次加载资源时,由于强制缓存优先级较高,先比较当前时间与上一次返回 200 时的时间差,如果没有超过 cache-control
设置的 max-age
,则没有过期,并命中强缓存,直接从本地读取资源。如果浏览器不支持HTTP1.1,则使用 expires 头判断是否过期
【】如果资源已过期,则表明强制缓存没有被命中,则开始协商缓存,向服务器发送带有 If-None-Match
和 If-Modified-Since
的请求
【】服务器收到请求后,优先根据 Etag
的值判断被请求的文件有没有做修改,Etag 值一致则没有修改,命中协商缓存,返回 304;如果不一致则有改动,直接返回新的资源文件带上新的 Etag 值并返回 200
【】如果服务器收到的请求没有 Etag 值,则将 If-Modified-Since
和被请求文件的最后修改时间做比对,一致则命中协商缓存,返回 304;不一致则返回新的 last-modified
和文件并返回 200
9、强缓存与协商缓存
【】强缓存字段:expires / cache-control
. 协商缓存字段:If-None-Match / Etag 、If-Modified-Since / Last-Modified
【】缓存字段优先级:Cache-control -> expires -> Etag -> last-modified
【】Cache-control 的值:max-age、s-maxage、public、private、no-store、no-cache
【】no-cache 、 no-store 的区别
- 这两个指令都可以在请求和响应中使用
no-store
是真正的不进行任何缓存no-cache
在请求头中使用时,表示强制使用协商缓存;在响应头中使用时,表示缓存服务器不能对资源进行缓存,客户端可以缓存资源,但每次使用缓存资源前都必须先向服务器确认其有效性
【】强缓存存在两种形式:
from memory cache
:资源在内存当中from disk cache
:资源在磁盘当中
10、点击刷新按钮或者按 F5、按 Ctrl+F5 (强制刷新)、地址栏回车有什么区别
【】点击刷新按钮或者按 F5:本地缓存文件直接过期,进行协商缓存
【】按 Ctrl+F5 (强制刷新): 直接相当于第一次请求
【】地址栏回车:强缓存开始
11、如何阻止事件冒泡
【】普通浏览器使用:event.stopPropagation()
【】IE浏览器使用:event.cancelBubble = true
12、哪些操作会造成内存泄漏
【】使用未声明的变量,而意外的创建了一个全局变量
【】设置了 setInterval 定时器,而忘记取消它,如果循环函数有对外部变量的引用的话,那么这个变量会被一直留在内存中,而无法被回收
【】获取一个 DOM 元素的引用,而后面这个元素被删除,由于我们一直保留了对这个元素的引用,所以它也无法被回收
【】不合理的使用闭包,从而导致某些变量一直被留在内存当中
13、浏览器资源解析机制
【】整体流程
- 浏览器开始解析
HTML
,此时document.readystate
为loading
- 解析中遇到不带
async
和defer
的script
脚本时,需要等待 script脚本下载完成并执行后,才会继续解析 HTML - 当文档完成解析,
document.readyState
变成interactive
,触发DOMContentLoaded
事件 - 此时文档完全解析完成,浏览器可能还在等待如图片等内容加载,等这些内容完成载入并且所有异步脚本完成载入和执行,
document.readyState
变为complete
,window
触发load
事件
【】浏览器解析不同资源时的行为
- 遇到CSS样式资源,CSS 异步下载,不会阻塞构建DOM树,但会阻塞渲染
- JS 会阻塞浏览器解析,但是带有defer 或 async 时,是并行下载JS脚本,延迟或异步解析执行
- CSS加载会阻塞后面的JS语句的执行。因为HTML5标准中有一项规定,浏览器在执行Script脚本前,必须保证当前的的外联CSS已经解析完成,因为JS可能会去获取或者变更DOM的CSS样式,如果此时外联CSS还没解析好,获取到的结果就是不准确的
- 解析遇到 Img图片 时,直接异步下载,不会阻塞解析;下载完毕后用图片替换原有src的地方
15、prefetch、preload
【】prefetch、preload都是告知浏览器提前加载文件;仅仅是加载资源,并不会执行
【】prefetch :其利用浏览器空闲时间来下载用户在不久的将来可能访问的资源(比如下一个页面)。<link href="/js/xx.js" rel="prefetch">;
加载完成后,浏览器在使用资源时自动从prefetch cache
读取该资源
【】preload : 可以指明哪些资源是在页面加载完成后
就需要的,这一机制使得资源可以更早的得到加载并可用,且更不易阻塞页面的初步渲染,进而提升性能