浏览器
浏览器的核心
- 渲染引擎:将网页代码渲染为用户视觉可以感知的平面文档
- JavaScript解释器(又称JavaScript引擎):读取网页中的 JavaScript 代码,对其处理后运行
渲染引擎
网页处理,通常分成四个阶段:(并非严格按顺序执行)
- 解析代码:HTML 代码解析为 DOM,CSS 代码解析为 CSSOM(CSS Object Model)
- 对象合成:将 DOM 和 CSSOM 合成一棵渲染树(render tree)
- 布局:计算出渲染树的布局(layout)
- 绘制:将渲染树绘制到屏幕
其中,渲染树转换为网页布局,称为“布局流”(flow);布局显示到页面的过程,称为“绘制”(paint)。两者均有阻塞效应。
注意,重流(reflow)和重绘(repaint)不一定一起发生,重流必然导致重绘,重绘不一定需要重流。
优化技巧
- 使用documentFragment操作DOM
- 缓存 DOM 信息
- 使用 CSS class 一次性改变样式
- 使用window.requestAnimationFrame(),因为它可以把代码推迟到下一次重流时执行,而不是立即要求页面重流
- 使用虚拟DOM(virtual DOM)库
window
关于window对象的几条恒等式
window.window === window window.self === window window.open().opener === window frames === window window.frames === window
Cookie
服务器保存在浏览器的一小段文本信息,每个Cookie的大小一般不能超过4KB。
- 分辨两个请求是否来自同一个浏览器
- 保存状态信息:用户偏好,记录和分析用户行为
- 对话(session)管理:保存登录信息等
Cookie包含如下信息
- Cookie 的名字
- Cookie 的值(数据信息)
- 到期时间
- 所属域名(默认是当前一级域名)当前发送Cookie的域名的一部分
- 生效的路径(默认是当前网址)必须为绝对路径
浏览器的同源政策规定,两个网址只要域名相同和端口相同,就可以共享 Cookie。
Cookie由HTTP协议生成,供HTTP协议使用
- HTTP 回应:Cookie 生成
- HTTP 请求:Cookie 发送
浏览器向服务器发送Cookie时,Cookie字段是使用一行将所有Cookie全部发送;服务器向浏览器设置Cookie时,Set-Cookie字段是一行只设置一个Cookie。
HttpOnly
该属性指定该Cookie无法通过JavaScript脚本拿到,以下均不可:
- Document.cookie属性
- XMLHttpRequest对象
- Request API
Session
Session是基于Cookie的持久化机制的一种会话机制。
- Cookie由服务器设置,浏览器保存
- 防篡改机制:Cookie添加签名
- 安全起见,Cookie中只设置Session Id,具体的Session信息保存在服务器
浏览器数据库
客户端储存应该使用 Web storage API 和 IndexedDB
Web Storage
Storage接口用于脚本在浏览器保存数据。
- 键值对:字符串
- 文本格式
- 限制大小2.5-10M
遍历所有的键
for (var i = 0; i < window.localStorage.length; i++) { console.log(localStorage.key(i)); }
注意,Storage事件在导致数据变化的当前页面的同一个域名的其他窗口触发。
IndexedDB
浏览器提供的网页数据本地数据库 。
- 键值对:对象仓库
- 支持索引、事务
- 存储空间大,支持二进制存储
- 异步
- 同域限制
几个重要的对象
- IDBRequest / IDBOpenDBRequest:数据库连接
- IDBDatabase:数据库
- IDBObjectStore:仓库对象,由 transaction().objectStore() 返回
- IDBTransaction:事务对象,异步操作数据库事务,所有的读写操作都要通过这个对象进行
- IDBIndex:数据库索引
注意,事务的执行顺序是按照创建的顺序,而不是发出请求的顺序。只有监听到事务的complete事件,才能保证事务操作成功。
关于详细信息,请参见:IndexDB - 浏览器端数据库
同源限制
Same-origin policy,浏览器安全的基石。
- 保证用户信息安全,避免Cookie共享,防止恶意网站窃取数据
非同源会有以下问题
- 无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB
- 无法接触非同源网页的 DOM
- 无法向非同源地址发送 AJAX 请求(可以发送,但浏览器会拒绝接受响应)
- 父窗口与子窗口无法通信
对于完全不同源的网站,目前有两种方法,可以解决跨域窗口的通信问题
- 片段识别符(fragment identifier)
- 跨文档通信API(Cross-document messaging)
[1]. fragment identifier
方法:破解
window.onhashchange = checkMessage; function checkMessage() { var message = window.location.hash; /// 获取识别符 }
[2]. window.postMessage()
跨文档通信 API(Cross-document messaging),支持跨窗口通信。
父窗口和子窗口都可以通过message事件,监听对方的消息:
message事件的参数是事件对象event
,提供以下三个属性。
event.source:
发送消息的窗口event.origin:
消息发向的网址event.data
::消息内容