本地存储的几种对比
本地存储的几种简单对比
1、cookie:4K,可以手动设置失效期 2、localStorage:5M,除非手动清除,否则一直存在 3、sessionStorage:5M,不可以跨标签访问,页面关闭就清理 4、indexedDB:浏览器端数据库,无限容量,除非手动清除,否则一直存在 5、service worker 实现离线缓存
SW 除了 work 线程的限制外,由于可拦截页面请求,为了保证页面安全,浏览器端对 sw 的使用限制也不少。
1)无法直接操作 DOM 对象,也无法访问 window、document、parent 对象。可以访问 location、navigator;
2)可代理的页面作用域限制。默认是 sw.js 所在文件目录及子目录的请求可代理,可在注册时手动设置作用域范围;
3)必须在 https 中使用,允许在开发调试的 localhost 使用。
浏览器的本地存储技术主要用于在客户端保存数据,以减少对服务器的请求,提升用户体验。常见的浏览器本地存储技术包括 Cookie、LocalStorage、SessionStorage 和 IndexedDB。以下是它们的详细对比:
1. Cookie
1.1 特点
- 存储大小:最多 4KB。 
- 生命周期:可以设置过期时间,默认在浏览器关闭时失效。 
- 作用域:可以设置作用域(Domain 和 Path)。 
- 通信方式:每次 HTTP 请求都会携带 Cookie,增加请求头的大小。 
1.2 适用场景
- 会话管理:如用户登录状态。 
- 个性化设置:如用户偏好设置。 
- 跟踪用户行为:如广告跟踪。 
1.3 优缺点
- 优点: - 兼容性好,所有浏览器都支持。 
- 可以设置过期时间。 
 
- 缺点: - 存储空间小。 
- 每次请求都会携带,增加网络开销。 
 
2. LocalStorage
2.1 特点
- 存储大小:通常为 5MB(不同浏览器可能不同)。 
- 生命周期:永久存储,除非手动清除。 
- 作用域:同一域名下的所有页面共享。 
- 通信方式:仅在客户端存储,不会随请求发送。 
2.2 适用场景
- 持久化数据:如用户偏好设置、缓存数据。 
- 离线数据存储:如保存用户未提交的表单数据。 
2.3 优缺点
- 优点: - 存储空间较大。 
- 数据永久存储,除非手动清除。 
 
- 缺点: - 仅支持字符串类型的数据。 
- 不适合存储敏感数据。 
 
3. SessionStorage
3.1 特点
- 存储大小:通常为 5MB(不同浏览器可能不同)。 
- 生命周期:仅在当前会话有效,关闭浏览器或标签页后数据被清除。 
- 作用域:仅在当前标签页有效,不同标签页不共享。 
- 通信方式:仅在客户端存储,不会随请求发送。 
3.2 适用场景
- 临时数据存储:如表单数据、页面状态。 
- 单页应用(SPA)的状态管理。 
3.3 优缺点
- 优点: - 存储空间较大。 
- 数据仅在当前会话有效,安全性较高。 
 
- 缺点: - 数据生命周期短,关闭浏览器后失效。 
- 仅支持字符串类型的数据。 
 
4. IndexedDB
4.1 特点
- 存储大小:通常为 50MB 以上(不同浏览器可能不同)。 
- 生命周期:永久存储,除非手动清除。 
- 作用域:同一域名下的所有页面共享。 
- 通信方式:仅在客户端存储,不会随请求发送。 
- 数据类型:支持存储复杂数据类型(如对象、数组)。 
4.2 适用场景
- 大量结构化数据存储:如离线应用、缓存大量数据。 
- 复杂查询需求:如需要索引和查询的数据。 
4.3 优缺点
- 优点: - 存储空间大。 
- 支持复杂数据类型和索引。 
- 适合存储大量数据。 
 
- 缺点: - API 较复杂,使用难度较高。 
- 兼容性较差(旧版浏览器可能不支持)。 
 
5. 对比总结
特性
Cookie
LocalStorage
SessionStorage
IndexedDB
存储大小
4KB
5MB
5MB
50MB 以上
生命周期
可设置过期时间
永久存储
会话级别
永久存储
作用域
可设置 Domain 和 Path
同一域名下共享
当前标签页有效
同一域名下共享
通信方式
每次请求携带
不随请求发送
不随请求发送
不随请求发送
数据类型
字符串
字符串
字符串
复杂数据类型(对象、数组等)
适用场景
会话管理、用户跟踪
持久化数据、缓存
临时数据存储
大量结构化数据存储
兼容性
所有浏览器
所有现代浏览器
所有现代浏览器
大部分现代浏览器
6. 如何选择合适的存储技术?
- 小量数据且需要随请求发送:选择 Cookie。 
- 持久化存储且数据量较大:选择 LocalStorage。 
- 临时存储且数据量较大:选择 SessionStorage。 
- 大量结构化数据存储:选择 IndexedDB。 
7. 最佳实践
- 敏感数据:避免在客户端存储敏感数据(如密码、令牌),即使存储也要加密。 
- 数据清理:定期清理无用数据,避免占用过多存储空间。 
- 兼容性处理:在使用 IndexedDB 等新技术时,注意兼容性问题,提供降级方案。 
通过合理选择和使用浏览器本地存储技术,可以显著提升 Web 应用的性能和用户体验。
session 和 cookie
cookie
Cookie 是由客户端保存的小型文本文件,其内容为一系列的键值对.Cookie 是由 HTTP 服务器设置的,保存在浏览器中.
- 浏览器向某个 URL 发起 HTTP 请求(可以是任何请求,比如 GET 一个页面、POST 一个登录表单等) 
- 对应的服务器收到该 HTTP 请求,并计算应当返回给浏览器的 HTTP 响应。 
- 在响应头加入 Set-Cookie 字段,它的值是要设置的 Cookie。 
- 浏览器收到来自服务器的 HTTP 响应。 
- 浏览器在响应头中发现 Set-Cookie 字段,就会将该字段的值保存在内存或者硬盘中。 
- 浏览器下次给该服务器发送 HTTP 请求时, 会将服务器设置的 Cookie 附加在 HTTP 请求的头字段 Cookie 中。浏览器可以存储多个域名下的 Cookie,但只发送当前请求的域名曾经指定的 Cookie, 这个域名也可以在 Set-Cookie 字段中指定) 
- 服务器收到这个 HTTP 请求,发现请求头中有 Cookie 字段, 便知道之前就和这个用户打过交道了。 
- 过期的 Cookie 会被浏览器删除。 
服务器通过 Set-Cookie 响应头字段来指示浏览器保存 Cookie, 浏览器通过 Cookie 请求头字段来告诉服务器之前的状态。 Cookie 中包含若干个键值对,每个键值对可以设置过期时间。
cookie 的属性
- Max-Age 
- 定义: 指定 Cookie 的有效期,以秒为单位 
- 行为: - 如果 Max-Age 为正数,浏览器会将其持久化,即写入到对应的 Cookie 文件中。 
- 如果 Max-Age 为零或负数,浏览器会立即删除该 Cookie。 
 
- 优先级: 如果同时设置了 Expires 和 Max-Age,Max-Age 的优先级更高。 
- Expires 
- 定义: 指定 Cookie 的过期时间,格式为 GMT 时间。 
- 行为: - 如果未设置 Expires,则默认为会话 Cookie,即浏览器关闭时删除。 
- 如果设置了 Expires,则为持久性 Cookie,直到指定的时间点过期。 
 
- 注意: Expires 的值与客户端的时区相关 
- Domain 
- 定义: 指定 Cookie 可以发送到的主机名。 
- 行为: - 如果未指定,默认为当前文档访问地址中的主机部分(不包含子域名)。 
- 例如,设置 Domain=.example.com,则 a.example.com 和 b.example.com 都可以访问该 Cookie。 
 
- 限制: 不能跨域设置 Cookie,例如,无法将 Domain 设置为 baidu.com。 
- Secure 
- 定义: 指示浏览器仅通过 HTTPS 协议发送该 Cookie。 
- 行为: - 只有在使用 HTTPS 协议时,浏览器才会发送该 Cookie。 
- 有助于保护 Cookie 在传输过程中的安全性。 
 
- HttpOnly 
- 定义: 指示浏览器禁止客户端脚本(如 JavaScript)访问该 Cookie。 
- 行为: - 防止通过 document.cookie 等方式访问 Cookie。 
- 有助于防止跨站脚本攻击(XSS) 
 
- SameSite 
- 定义: 指示浏览器在跨站请求时是否发送该 Cookie。 
- 取值: - Strict:仅在同一站点的请求中发送 Cookie。 
- Lax:在部分跨站请求中发送 Cookie,例如,GET 请求导航到目标站点时。 
- None:在所有跨站请求中发送 Cookie,但需要同时设置 Secure 属性。 
 
- 注意: Chrome 80 版本后,默认值为 Lax。 
cookie 防篡改机制
服务器可以为每个 cookie 项生成签名, 由于用户篡改 cookie 后无法生成对应的签名, 服务器便可以得知用户对 cookie 进行了篡改
- 在服务器中配置一个不为人知的字符串(secret), 比如: x&sjh23; 
- 在服务器需要设置 cookie 时,比如(authed=false), 不仅设置 authed 的值为 false, 在值的后面进一步设置一个签名, 最终设置的 cookie 是 authed=false|6hTiBl7lVpd1P; 
- 签名 6hTiBl7lVpd1P 是这样生成的:Hash('x&sjh23'+'false')。 要设置的值与 Secret 相加再取哈希。 
- 用户收到 HTTP 响应并发现头字段 Set-Cookie: authed=false|6hTiBl7lVpd1P。 
- 用户在发送 HTTP 请求时,篡改了 authed 值,设置头字段 Cookie: authed=true|???。 因为用户不知道 Secret,无法生成签名,只能随便填一个。 
- 服务器收到 HTTP 请求,发现 Cookie: authed=true|???。服务器开始进行校验: Hash('true'+'x&sjh23'),便会发现用户提供的签名不正确。 
因为 Cookie 是明文传输的, 只要服务器设置过一次 authed=true|xxxx 我不就知道 true 的签名是 xxxx 了么, 以后就可以用这个签名来欺骗服务器了。因此 Cookie 中最好不要放敏感数据。 一般来讲 Cookie 中只会放一个 Session Id,而 Session 存储在服务器端。
cookie 跨域
- 通过这是 nginx 代理服务器, 将两个服务器域名统一到一个反向代理服务器 
upstream www.test.com {
        server 127.0.0.1:8080 weight=1;
        server 127.0.0.1:8060 weight=1;
    }
    server {
        listen       80;
        server_name  www.test.com;
        # charset koi8-r;
        # access_log  logs/host.access.log  main;
        location / {
        proxy_pass   http://www.test.com;
        index  index.html index.htm;
        }
    }- CORS 协议 前端: 客户端使用 XMHLHttpRequest 发起 Ajax 请求,当前绝大部分浏览器已经支持 CORS 方式,且主流浏览器均提供了对跨域资源共享的支持。 
让后台修改,支持某些前端域名的跨域。php 代码如下:
header('Access-Control-Allow-Origin:'); //支持所有前端域名,但是有个问题,就是不支持 Cookie 的跨域
也可以动态设置跨域。header('Access-Control-Allow-Origin:'.$_SERVER['HTTP_ORIGIN']);//如果请求涉及到跨域,那么 origin 会自动带上前端域名信息。这样做还有一个好处,可以支持 cookie 跨域
对于 nodejs 做如下配置可允许资源的跨域访问:
//设置CORS跨域访问
app.all("*", function (req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header(
    "Access-Control-Allow-Headers",
    "X-Requested-With, accept, origin, content-type"
  );
  res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
  res.header("X-Powered-By", " 3.2.1");
  res.header("Content-Type", "application/json;charset=utf-8");
  next();
});Access-Control-Allow-Origin:* 表示允许任何域发起请求,如果只允许特定的域访问,则设置 Access-Control-Allow-Origin:xxx 为具体域名即可。
- 怎么让 Ajax 请求都带上 Cookie & cookie 跨域 
客户端需要设置 Ajax 请求属性 withCredentials=true
对于 XMLHttpRequest 的 Ajax 请求
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.withCredentials = true; // 携带跨域cookie
xhr.send();axios.defaults.withCredentials=true; // 让ajax携带cookie服务端进行设置
res.header("Access-Control-Allow-Credentials:true");
// 服务端header设置Access-Control-Allow-Credentials:true后,Access-Control-Allow-Origin不可以设为*,必须设置为一个域名,否则回返回错误
// 服务器端使用 CORS 协议解决跨域访问数据问题时,需要设置响应消息头 Access-Control-Allow-Credentials 值为“true”。
// 同时,还需要设置响应消息头 Access-Control-Allow-Origin 值为指定单一域名(注:不能为通配符“*”)。设置 1. 解决顶级域名与二级域名之间的 cookie 跨域问题
- 通过设置 domain 
顶级域名服务器与二级域名服务器之间哪个设置都能生效
设置完毕后写回到客户端,用另一个服务器即可访问此 Cookie
二级域名能读取设置了 domain 为顶级域名或者自身的 cookie,不能读取其他二级域名 domain 的 cookie。例如:要想 cookie 在多个二级域名中共享,需要设置 domain 为顶级域名,这样就可以在所有二级域名里面或者到这个 cookie 的值了。
顶级域名只能获取到 domain 设置为顶级域名的 cookie,domain 设置为其他子级域名的无法获取。 读取 COOKIE
修改 cookie
- 顶级域名 顶级域名的 cookie 在顶级域名或者非顶级域名[需要设置 domain 为顶级域名才可以] 都可以修改. 
#为所有二级域名设置一个 cookie setcookie("name", "yangbai", time() + 1000, "/", "yangbai.com");
#在game.yangbai.com下面修改这个cookie值
setcookie("name", "yangbai11", time() + 1000, "/", "yangbai.com");- 二级域名 
修改二级域名自身生成的 cookie 不需要设置 domain, 直接设置即可
#修改game.yangbai.com下面自身的cookie值
setcookie("game", "chip", time() + 10000)删除 cookie
#删除 yangbai.com 下面的 cookie 值 setcookie("name", null, time() - 1000, "/", "yangbai.com");
#删除 game.yangbai.com 下面自身的 cookie 值 setcookie("game", null, time() - 1000);
- jsonp 
将 get 请求伪装成一个 script 文件的加载。就可以绕过跨域的问题为了。
function jsonp(url, data, callback) {
  var script = document.createElement("script");
  script.src = url + "?" + data + "&callback=" + callback;
  document.body.appendChild(script);
}session
Session 是存储在服务器端的,避免了在客户端 Cookie 中存储敏感数据。 Session 可以存储在 HTTP 服务器的内存中,也可以存在内存数据库(如 redis)中, 对于重量级的应用甚至可以存储在数据库中。
- 用户提交包含用户名和密码的表单,发送 http 请求. 
- 服务器验证用户发来的用户密码. 
- 如果正确则把当前用户名存储到 redis 中,并生成它在 redis 中的 id.这个 ID 称为 Session ID,通过 Session ID 可以从 Redis 中取出对应的用户对象, 敏感数据(比如 authed=true)都存储在这个用户对象中。 
- 设置 Cookie 为 sessionId=xxxxxx|checksum 并发送 HTTP 响应, 仍然为每一项 Cookie 都设置签名。 
- 用户收到 HTTP 响应后,便看不到任何敏感数据了。在此后的请求中发送该 Cookie 给服务器。 
- 服务器收到此后的 HTTP 请求后,发现 Cookie 中有 SessionID,进行防篡改验证。 
- 如果通过了验证,根据该 ID 从 Redis 中取出对应的用户对象, 查看该对象的状态并继续执行业务逻辑。 
Web 应用框架都会实现上述过程,在 Web 应用中可以直接获得当前用户。 相当于在 HTTP 协议之上,通过 Cookie 实现了持久的会话。这个会话便称为 Session。
localStorage 和 sessionStorage 区别
特性 SessionStorage LocalStorage 跨标签页 不能跨标签页共享 | 可以跨标签页共享 作用域 当前标签页 | 同一域名下的所有标签页 生命周期 会话级别,关闭标签页后失效 | 永久存储,除非手动清除 适用场景 临时数据存储 | 持久化数据存储 如果需要 跨标签页共享数据,使用 LocalStorage。 | 如果数据仅需在 当前标签页 使用,使用 SessionStorage。
如果需要更复杂的跨标签页通信,可以使用 LocalStorage 事件
最后更新于
这有帮助吗?