一文梳理Web存储,从cookie,WebStorage到IndexedDB
前言
HTTP是无状态的协议,网络早期最大的问题之一是如何管理状态。服务器无法知道两个请求是否来自同一个浏览器。cookie应运而生,开始出现在各大网站,然而随着前端应用复杂度的提高,Cookie 也渐渐演化为了一个“存储多面手”,承载了 自身仅有的4KB 内存所不能承受的压力。在这样的背景下,web Storage应运而生,专门用于浏览器存储。但web Storage也仅仅是cookie的扩展,只能用于存储少量的简单数据,当遇到大规模的、结构复杂的数据时,Web Storage 也爱莫能助。这时候,就不得不其强大的IndexedDB了,一个运行在浏览器上的非关系型数据库。本文从cookie讲起,Web Storage过渡,IndexedDB结尾,梳理一下web 存储的体系与知识,希望在帮助作者梳理知识体系的同时也能帮助到广大前端ers!
cookie
由于http是无状态的协议,一旦客户端和服务器的数据交换完毕,就会断开连接,再次请求,会重新连接,服务器单从网络连接上无法知道用户身份。怎么办呢?那就给每次新的用户请求时,给它颁发一个身份证(独一无二)吧,下次访问,必须带上身份证,这样服务器就会知道是谁来访问了,针对不同用户,做出不同的响应,这就是Cookie的原理。
Cookie 的本职工作并非本地存储,而是“维持状态”。它是浏览器存储在用户机器的一个小文本文件,大小不能超过4k,并且一些浏览器甚至会限制cookie的数量。Cookie是纯文本,没有可执行代码。储存一些服务器需要的信息,每次请求站点,会发送相应的cookie,这些cookie可以用来辨别用户身份信息等作用。
cookie的编码方式为encodeURI()。
cookie类型
cookie按照过期时间分为两类:会话cookie和持久cookie。
会话cookie是一种临时cookie,对标session,当用户退出浏览器,会话cookie就会被删除。默认情况下,即不设置过期时间,设置的cookie为会话cookie。持久cookie则会储存在硬盘里,保留时间更长,不以浏览器的关闭为转移,通常是持久性的cookie会维护某一个用户周期性访问服务器的配置文件或者登录信息。
cookie的属性
domain(cookie的域)
产生Cookie的服务器可以向set-Cookie响应首部添加一个domain属性来控制哪些站点可以看到那个cookie,例如下面:
Set-Cookie:name="losstie";domain="m.baidu.com"
如果用户访问m.baidu.com就会发送这个cookie,不是则不会。
path(cookie的路径 )
path 参数告诉浏览器 cookie 的路径。默认情况下,cookie 属于当前页面。
secure
设置了属性secure,cookie只有在https协议加密情况下才会发送给服务端。但是这并不是最安全的,由于其固有的不安全性,敏感信息也是不应该通过cookie传输的。
HttpOnly
禁止javascript操作cookie(为避免跨域脚本(xss)攻击,通过javascript的document.cookie无法访问带有HttpOnly标记的cookie。)
SamSite
Cookie 的SameSite
属性用来限制第三方 Cookie,从而减少安全风险。它可以设置三个值:
- Strict 完全禁止第三方 Cookie,跨站点时,任何情况下都不会发送 Cookie。换言之,只有当前网页的 URL 与请求目标一致,才会带上 Cookie。
- Lax 规则稍稍放宽,大多数情况也是不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外。导航到目标网址的 GET 请求,只包括三种情况:链接,预加载请求,GET 表单
- None Chrome 计划将
Lax
变为默认设置。这时,网站可以选择显式关闭SameSite
属性,将其设为None
。不过,前提是必须同时设置Secure
属性(Cookie 只能通过 HTTPS 协议发送),否则无效。
cookie操作
通过docuemnt.cookie可以设置和获取Cookie的值
/* cookie */
function set(key, value){
document.cookie = key + "=" + value;
}
function get(key){
var all = document.cookie;
var s = all.indexOf(key)+key.toString().length+1;
var e = all.indexOf(";",s);
return all.substring(s,e);
}
function remove(key){
var e = "expires=" + new Date(1970,1,1); // 标注过去的时间
document.cookie = key + "=;" + e;
}
第三方cookie
通常cookie的域和浏览器地址的域匹配,这被称为第一方cookie。第三方cookie就是cookie的域和地址栏中的域不匹配,这种cookie通常被用在第三方广告网站。用于跟踪用户的浏览记录,并且根据收集的用户的浏览习惯,给用户推送相关的广告。
cookie的劣势
- Cookie 不够大,体积不能超过4k,当 Cookie 超过 4KB 时,它将面临被裁切的命运。这样看来,Cookie 只能用来存取少量的信息。
- 每次都会携带在http头中,过量的cookie会损耗性能。
- cookie是紧跟域名的,同一个域名下的所有请求,都会携带 Cookie。
- 不够安全,服务器没法分辨用户和攻击者,攻击者可以读取网络上的其他用户的信息,包含HTTP Cookie的全部内容,以便进行中间的攻击。使用跨站点脚本技术可以窃取cookie等。
Web Storage
Internet Explorer 8+, Firefox, Opera, Chrome, 和 Safari支持Web 存储。
Web Storage 是 HTML5 专门为浏览器存储而提供的数据存储机制。它又分为 Local Storage 与 Session Storage。localStorage与sessionStorage保存的数据,以“键值对”的形式存在,并都是以文本格式保存。
localStorage与sessionStorage的区别
两者的区别在于生命周期与作用域的不同。
- 生命周期: Local Storage 是持久化的本地存储,存储在其中的数据永远不会过期,只能是手动删除。Session Storage 是临时性的本地存储,它是会话级别的存储,当会话结束(页面被关闭)时,存储内容也随之被释放。
- 作用域:Local Storage、Session Storage 和 Cookie 都遵循同源策略。但 Session Storage 在遵循同源策略的前提下,还需要在同一窗口。只要它们不在同一个浏览器窗口中打开,那么它们的 Session Storage 内容便无法共享。
方法
不管是 localStorage,还是 sessionStorage,可使用的API都相同。以localStorage为例:
- 保存数据:localStorage.setItem(key,value);
- 读取数据:localStorage.getItem(key);
- 删除单个数据:localStorage.removeItem(key);
- 删除所有数据:localStorage.clear();
- 得到某个索引的key:localStorage.key(index);
module.exports = {
set:set,
get:get,
remove:remove,
removeAll:removeAll,
each:each
}
function set(key ,val){
localStorage.setItem(key, JSON.stringify(val));
};
function get(key){
return JSON.parse(localStorage.getItem(key));
};
function remove(key){
localStorage.removeItem(key);
};
function removeAll(){
localStorage.clear();
};
function each(fn){
pluck(localStorage, function(val, key){
fn(val, key);
return false;
});
}
function pluck(obj, fn){
if(isList(obj)) {
for(var i = 0; i<obj.length;i++){
if(fn(obj[i], i)) {
return obj[i];
}
}
} else {
for(var key in obj) {
if(obj.hasOwnProperty(key)){
if(fn(obj[key], key)){
return obj[key];
}
}
}
}
}
function isList(val) {
return (val != null && typeof val != 'function' && typeof val.length == 'number')
}
function isFunction(val) {
return val && Object.prototype.toString.call(val) === '[object Function]'
}
function isObject(val) {
return val && Object.prototype.toString.call(val) === '[object Object]'
}
Web Storage 特点
- 存储容量大: Web Storage 根据浏览器的不同,存储容量可以达到 5-10M 之间。Chrome、FireFox、Edge 都是 5M(IE 忽略)。
- 仅位于浏览器端,不与服务端发生通信。
应用场景
localStorage:
- 缓存静态资源,比如图片内容丰富的电商网站会用它来存储 Base64 格式的图片字符串或者存储一些不经常更新的 CSS、JS 等静态资源。
- 作为前端 DB 的存储介质
sessionStorage:
- 用来存储生命周期和它同步的会话级别的信息。比如存储用户输入的内容,当页面刷新的时候可以立刻显示出刷新前的内容
IndexedDB
IndexedDB 是一个运行在浏览器上的非关系型数据库。理论上来说,IndexedDB 是没有存储上限的(一般来说不会小于 250M)。它不仅可以存储字符串,还可以存储二进制数据。
IndexedDB特点
- 键值对储存,IndexedDB 内部采用对象仓库(object store)存放数据。
- 异步,ndexedDB 操作时不会锁死浏览器,用户依然可以进行其他操作(与 LocalStorage 形成对比,后者的操作是同步的)。
- 支持事务,只要有一步失败,整个事务就都取消,数据库回滚到事务发生之前的状态,不存在只改写一部分数据的情况。
- 同源限制,每一个数据库对应创建它的域名。网页只能访问自身域名下的数据库,而不能访问跨域的数据库。
- 存储空间大,一般来说不少于 250MB,甚至没有上限。
- 支持二进制储存,仅可以储存字符串,还可以储存二进制数据(ArrayBuffer 对象和 Blob 对象)。
常见操作
IndexedDB大部分操作并不是常用的调用方法,返回结果的模式,而是请求——响应的模式。
建立打开IndexedDB ----
window.indexedDB.open("testDB")
关闭IndexedDB----
indexdb.close()
删除IndexedDB----
indexedDB.deleteDatabase(indexdb)
应用场景
在 IndexedDB 中,我们可以创建多个数据库,一个数据库中创建多张表,一张表中存储多条数据——这足以 hold 住复杂的结构性数据。
- 不需要网络连接的离线纯应用,比如Todolist这类用来记录待办任务类型的应用。
- 需要存储大量数据的应用,比如图书馆管理系统这类存储大量数据的应用;
- 配合service work构建pwa应用,用于缓存网络请求。
cookie/webStorage/IndexedDB区别
小结
浏览器存储、缓存技术的出现和发展,为前端应用带来了无限的转机,页面越发复杂,功能越发强大。可以说,现代前端应用,尤其是移动端应用,之所以可以发展到在体验上叫板 Native 的地步,web存储功不可没(还有缓存)。
拓展学习
深入了解浏览器存储--从cookie到WebStorage、IndexedDB
一文梳理Web存储,从cookie,WebStorage到IndexedDB的更多相关文章
- web存储中cookie、session区别
http协议是一种无状态的协议,浏览器对服务器的每一次请求都是独立的.为了使得web能够产生一些动态信息,就需要保存”状态”,而cookie和session机制就是为了解决http协议无状态而产生.c ...
- html5的web存储与cookie的区别
以下从3个方面进行比较: 1,容量:cookie只有4KB,localStorage和sessionStorage最大容量5M 2,是否会携带到ajax中:cookie由每个对服务器的请求来传递,会影 ...
- 【高级功能】使用Web存储
Web存储允许我们在浏览器里保存简单的键/值数据.Web存储和cookie很相似,但它有着更好的实现方式,能保存的数据量也很大.这两种类型共享相同的机制,但是被保存数据的可见性和寿命存在区别. PS: ...
- 【温故而知新-Javascript】使用Web存储
Web存储允许我们在浏览器里保存简单的键/值数据.Web存储和cookie很相似,但它有着更好的实现方式,能保存的数据量也很大.这两种类型共享相同的机制,但是被保存数据的可见性和寿命存在区别. PS: ...
- HTML5——web存储 Web SQL 数据库 应用程序缓存 Web Workers 服务器发送事件 WebSocket
web存储 比cookie更好的本地存储方式 localStorage - 用于长久保存整个网站的数据,保存的数据没有过期时间,直到手动去除. sessionStorage - 用于临时保存同一窗口( ...
- JavaScript高级编程———数据存储(cookie、WebStorage)
JavaScript高级编程———数据存储(cookie.WebStorage) <script> /*Cookie 读写删 CookieUtil.get()方法根据cookie的名称获取 ...
- web存储之webstorage
web存储分类 客户端和服务端 认识web存储 随着web应用的发展,是的客户端存储的用途越来越多,然而实现客户端端存储的方式也是越来越多样化.最简单最兼容的方式就是cookie,但作为真正的客户端存 ...
- 数据存储之Cookie和Web Storage。
Cookie Cookie,有时也用其复数形式Cookies,指某些网站为了辨别用户身份.进行session跟踪而储存在用户本地终端上的数据(通常经过加密).接下来就谈谈cookie的一些利弊,coo ...
- Web存储机制—sessionStorage,localStorage使用方法
Web存储机制,在这里主要聊有关于Web Storage API提供的存储机制,通过该机制,浏览器可以安全地存储键值对,比使用cookie更加直观.接下来简单的了解如何使用这方面的技术. 基本概念 W ...
随机推荐
- .NetCore对接各大财务软件凭证API——用友系列(2)
一. 前言 今天我们继续来分析用友系列的第二个产品--U8Cloud2.5 ,apilink方式的API.官网的API文档地址如下:U8API文档 因为我们主要是凭证对接,所以使用到的模块有总账.基础 ...
- linux pinmux 引脚多路复用驱动分析与使用
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/code_style/article/de ...
- [Linux之旅一] .NET Core 2.2部署到Docker中
第一步,使用VS2017或者VS2019创建.NET Core 2.2或3.1的项目,如下图: 在创建项目的时候记得勾选Docker支持,这样会自动创建Dockerfile文件,这个文件用于构建Doc ...
- 【实战】基于OpenCV的水表字符识别(OCR)
目录 1. USB摄像头取图 2. 图像预处理:获取屏幕ROI 2.1. 分离提取屏幕区域 2.2. 计算屏幕区域的旋转角度 2.3. 裁剪屏幕区域 2.4. 旋转图像至正向视角 2.5. 提取文字图 ...
- STL容器操作
目录 1. 数组 2. Vector 3. List 3.1. std::forward_list 4. Tuple 4.1. 运行期索引 4.2. 元组合并 4.3. 元祖遍历 5. Pair 6. ...
- 从零开始的Spring Boot(4、Spring Boot整合JSP和Freemarker)
Spring Boot整合JSP和Freemarker 写在前面 从零开始的Spring Boot(3.Spring Boot静态资源和文件上传) https://www.cnblogs.com/ga ...
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(七)
系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...
- 这一次搞懂Spring的Bean实例化原理
文章目录 前言 正文 环境准备 两个重要的Processor 注册BeanPostProcessor对象 Bean对象的创建 createBeanInstance addSingletonFactor ...
- Java并发--ReentrantLock原理详解
ReentrantLock是什么? ReentrantLock重入锁,递归无阻塞的同步机制,实现了Lock接口: 能够对共享资源重复加锁,即当前线程获取该锁,再次获取不会被阻塞: 支持公平锁和非公平锁 ...
- Spring中的AOP(一)
1. Spring AOP实现机制 Spring采用动态代理机制和字节码生成技术实现AOP.与最初的AspectJ采用编译器将横切逻辑织入目标对象不同,动态代理机制和字节码生成都是在运行期间为目标对象 ...