浏览器

227 阅读8分钟

浏览器基础

1. 事件机制

(1) 事件触发三阶段

  • 捕获阶段:当达到某个条件触发了某个元素绑定的事件的时候,就会从document顶级元素发送一个事件流,顺着dom树一层一层向下查找,直到找到目标元素,这个层层查找的过程称为事件的捕获,在这个阶段不会触发绑定的事件。
  • 目标阶段:达到目标元素,这个阶段称为事件目标处理函数,触发这个元素绑定的事件。
  • 冒泡阶段:事件从目标元素一层层往顶层元素传递,这个过程中如果发现元素绑定了此类型的事件,就会触发,这就是事件冒泡。阻止冒泡可以用e.stopPropagation()或e.camcelBubble=true(IE)

(2)addEventListener 捕获事件和冒泡事件

  • 可解决的问题:解决节点重复事件绑定时,因为执行顺序的问题,前面绑定的相同事件会被覆盖的问题。addEventListener可以针对一个节点绑定重复类型的事件
  • 差异:addEventListener的第三个参数默认值为false为执行事件冒泡行为,为true时执行事件捕获行为。

(3)事件委托(事件代理)

定义: 利用冒泡事件,只指定一个事件处理程序,就可以管理某一类型的所有事件。

为什么用事件委托: 相较于直接给目标注册事件优势是节省内存、不需要给子节点注销事件

原理: 利用冒泡原理实现,委托父级代为执行事件

适合用事件委托的事件: click、mousedown、mouseup、keydown、keyup、keypress

2. 跨域问题

(1)什么是跨域

当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域

(2)为什么浏览器要限制跨域访问

防止CSRF攻击

(3)如何解决跨域(待完成)

JSONP:

  • 优点:简单适用,兼容性好(兼容低版本IE)

  • 缺点:只支持get请求,不支持post

  • 核心思想:网页通过添加一个<script> 元素,向服务器请求JSON数据,服务器收到请求后,将数据放在一个指定名字的回调函数的参数位置传回来

  • 实现:

    • 原生:
    <script src="http://test.com/data.php?callback=dosomething"></script>
    // 向服务器test.com发出请求,该请求的查询字符串有一个callback参数,用来指定回调函数的名字
    // 处理服务器返回回调函数的数据
    <script type="text/javascript">
     function dosomething(res){
         // 处理获得的数据
         console.log(res.data)
     }
    </script>
    
    • jQuery ajax
    $.ajax({
     url: 'http://www.test.com:8080/login',
     type: 'get',
     dataType: 'jsonp',  // 请求方式为jsonp
     jsonpCallback: "handleCallback",    // 自定义回调函数名
     data: {}
     });
    
    • react中使用jsonP
    1.yarn add jsonp --save
    2.import JsonP from 'jsonp'
    3.JsonP('url',{},function(err, data){
        console.log(data)
    })
    

CORS:

postMessage:

document.domain:

location.hash:

http-proxy:

(4)预检请求:OPTIONS,携带实际请求的相关信息,获知服务器是否允许该实际请求(缓存时间内,同一请求无需再发起预检)

(5)简单请求:不会触发预检请求

(6)响应头相关字段

  • Access-Control-Allow-Origin: 允许访问的外域URI

  • Access-Control-Expose-Headers: 设置除Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma之外的允许浏览器访问的字段

  • Access-Control-Max-Age: 指定预检请求的结果能够被缓存多久

  • Access-Control-Allow-Credentials:当浏览器的credentials设置为true时是否允许浏览器读取response的内容

  • Access-Control-Allow-Methods:用于预检请求响应,实际请求允许的方法

  • Access-Control-Allow-Headers:用于预检请求响应,实际请求允许的头部字段

3. 存储

(1)cookie / localStorage / sessionStorage 各自的使用场景和差异

辅助参考:blog.csdn.net/zgrkaka/art…

  • cookie

    • 由服务端生成,保存在客户端(由于前后端有交互,所以安全性差,且浪费带宽)
    • 存储大小有限(最大 4kb )
    • 存储内容只接受 String 类型
    • 保存位置:
      • 若未设置过期时间,则保存在 内存 中,浏览器关闭后销毁
      • 若设置了过期时间,则保存在 系统硬盘 中,直到过期时间结束后才消失(即使关闭浏览器)
    • 数据操作不方便,原生接口不友好,需要自己封装
    • 应用场景
      • 判断用户是否登陆过网站,以便下次登录时能够实现自动登录(或者记住密码)
      • 保存登录时间、浏览次数等信息
  • session

    • 是后端关心的内容,依赖于 cookie(sessionID 保存在cookie中)
    • 保存在服务端
    • 存储大小无限制
    • 支持任何类型的存储内容
    • 保存位置:服务器内存,若访问较多会影响服务器性能
  • webStorage:

    • html5 提供的本地存储方案,包括两种方式:sessionStoragelocalStorage
    • 相比 cookie 这种传统的客户端存储方式,webStorage 有许多优点:
      • 保存在客户端,不与服务器通信,因此比 cookie 更安全、速度更快
      • 存储空间有限,但比 cookie 大(5MB)
      • 仅支持 String 类型的存储内容(和 cookie 一样)
      • html5 提供了原生接口,数据操作比 cookie方便
        • setItem(key, value) 保存数据,以键值对的方式储存信息。
        • getItem(key) 获取数据,将键值传入,即可获取到对应的value值。
        • removeItem(key) 删除单个数据,根据键值移除对应的信息。
        • clear() 删除所有的数据
        • key(index) 获取某个索引的key
    • localStorage
      • 持久化的本地存储,浏览器关闭重新打开数据依然存在(除非手动删除数据)。
      • 应用场景:长期登录、判断用户是否已登录,适合长期保存在本地的数据。
    • sessionStorage
      • 浏览器窗口关闭后数据被销毁。
      • 应用场景:敏感账号一次性登录。

(2)同源策略

同源策略是客户端浏览器规则,同源是指协议、域名、端口三者一致,不同源的资源之间不能互相访问,这样大大的限制了恶意攻击的发生。如一个恶意网站通过iframe嵌入支付宝页面,通过js获取登录信息,这在没有同源策略的限制下是很容易实现的。同源策略多是限制js读取非同源的dom数据,如果是直接引用非同源的静态资源是可以的。因为这些是公开的,但是你不能修改别人的运行规则。

4. 浏览器缓存

(1)缓存位置

注:对于大文件来说,大概率是不存储在内存中的,反之优先 当前系统内存使用率高的话,文件优先存储进硬盘

  • Service Worker(不常用)
    • 是运行在浏览器背后的独立线程,一般可以用来实现缓存功能。
    • 传输协议必须为 HTTPS
    • Service Worker 的缓存与浏览器其他内建的缓存机制不同,它可以让我们自由控制缓存哪些文件、如何匹配缓存、如何读取缓存,并且缓存是持续性的。
  • Memory Cache :内存中的缓存
    • 优点:读取速度快
    • 缺点:一旦我们关闭 Tab 页面,内存中的缓存也就被释放了。
    • 如何触发:当我们访问过页面以后,再次刷新页面,可以发现很多数据都来自于内存缓存
  • Disk Cache :存储在硬盘中的缓存
    • 优点:缓存在硬盘中,容量大
    • 缺点:读取速度慢
    • 如何触发:根据浏览器请求头
  • Push Cache:推送缓存(不常用)
    • 是 HTTP/2 中的内容,当以上三种缓存都没有命中时,它才会被使用。
    • 它只在会话(Session)中存在,一旦会话结束就被释放,并且缓存时间也很短暂

(2)缓存策略

  • 强缓存: 直接从本地副本比对读取,不去请求服务器,返回的状态码是 200。通过 Expires 和 Cache-Control
  • 协商缓存: 会去服务器比对,若没改变才直接读取本地缓存,返回的状态码是 304。Last-Modified 配合 If-Modified-Since, ETag 配合If-None-Match

(3)无缓存策略

  • 浏览器会采用一个启发式的算法,通常会取响应头中的 Date 减去 Last-Modified 值的 10% 作为缓存时间

(4)根据场景选择缓存策略

  • 根据场景选择缓存策略(HTML 一般不缓存、含有hash的文件名可以长时间缓存

4. DevTools 的使用

  • 模拟不同设备
  • 快速定位元素
  • 代码中添加 debugger 嵌入断点
  • 给JS 增加断点
  • 通过Element 面板查看HTML元素、CSS 样式属性
  • 通过 Network 面板查看请求耗时、API接口数据,模拟弱网环境
  • 通过 Application 查看 Cookie, LocalStorage, SessionStorage等信息

5. 浏览器渲染原理

  1. 处理 HTML 并构建 DOM 树。浏览器接收到HTML转化为DOM树(字节数组 -> 字符串 -> Token -> Node -> DOM)
  2. 处理 CSS构建 CSSOM 树。将CSS文件转化文CSSOM树(字节数组 -> 字符串 -> Token -> Node -> CSSOM)
  3. 将 DOM 与 CSSOM 合并成一个渲染树。
  4. 根据渲染树来布局,计算每个节点的位置。
  5. 调用 GPU 绘制,合成图层,显示在屏幕上
  • 如何让 <script> 不阻塞页面渲染:放在页面底部,使用defer和async

6. HTTP和TLS

  • HTTP 协议是基于TCP/IP 的应用层协议
  • HTTP 状态码
    • 200 成功返回
    • 301 永久跳转 、302 临时跳转
    • 4XX 客户端问题
    • 5XX 服务端问题
  • HTTPS 建立过程
    • 客户端发送请求连接到服务器的443端口(随机数1+支持的加密算法)
    • 服务器返回握手响应(随机数2+匹配的加密算法)
    • 服务器发送第二个响应返回数字证书(颁发机构、过期时间、服务端公钥、签名、域名信息等)
    • 客户端解析证书,验证是否有效,没问题则生成预主秘钥
    • 客户端用随机数1、随机数2和预主秘钥组装会话秘钥,用证书公钥加密,发给服务端
    • 服务端使用私钥解密获得会话密钥
    • 客户端通过会话密钥加密一条消息发给服务端
    • 服务端通过会话密钥加密一条消息回传给客户端