前端面试的经典问题:
保存在浏览器端,都是同源的。
| cookies | sessionStorage | localStorage | |
|---|---|---|---|
| 通信 | cookies 数据始终在同源的 http 请求中携带,都会在浏览器和服务器间来回传递 | 不会自动把数据发给服务器,仅在本地保存 | 不会自动把数据发给服务器,仅在本地保存 |
| 存储大小 | 不能超过4k | 可以达到5M或更大 | 可以达到5M或更大 |
| 有效时间 | 在设置的过期时间前一直有效,即使浏览器或窗口关闭 | 在当前浏览器窗口关闭后自动删除 | 存储持久数据,除非主动删除数据 |
| 作用域 | 在同源窗口中共享 | 不在不同窗口中共享 | 在同源窗口中共享 |
cookie 是存放在浏览器中的,在每一个浏览器安装目录下,都存在一个文件夹,存放着不同域下对应的 cookie。
当浏览器通过 http 请求某一个域时,此时浏览器就会将该域下面的 cookie 自动放入 request header 中。
此时如果很多无关紧要的数据都存放在 cookie 中,都会随着请求发送给后台,这样就无形当中增加了网络开销。
在localStorage出现之前,cookie一直背开发者所滥用,导致很多的无关紧要的数
据被请求携带到服务器。cookie也存在一些限制,每一个域下的cookie最多是4KB,
每一个域下的cookie最多存在20条。
Set-Cookie:
name = value;
expires = date;
max-age = secondes;
domain = domain;
path = path;
secure;
HttpOnly;
SameSite = Lax|Strict;
cookie 的键与值,name不区分大小写,value必须URL编码。
cookie 的过期时间,使用GMT表示,可以使用toUTCString()或者使用toGMTString()来获取。
console.log(new Date().toUTCString()) //Fri, 21 Oct 2022 05:39:03 GMT
console.log(new Date().toGMTString()) //Fri, 21 Oct 2022 05:39:03 GMT
expires=Fri, 21 Oct 2022 05:39:03 GMT,表示在2022年10月21日05 : 39分之
后失效。
如果在新增 cookie 的时候没有增加expires属性,则表示会话阶段,也就
是在浏览器关闭时,cookie 就消失。
expires是在 http1.0 中的属性,在 http1.1 中新增了max-age。
max-age表示从当前创建开始到cookie过期的时间。
max-age可以为三个值,负值,0,正值。
max-age为负值时,表示 cookie 为会话阶段。max-age为0时,表示删除 cookie。max-age的值为正数时,则 expires = max-age + 当前时间。domain 指定域,path 指定路径。
两者结合起来表示当浏览器向某一个域名和路径发送 http 请求时,需要携带符合域名和路径条件的 cookie。
例如 domain 设置为"baidu.com" , path 设置为"/",当浏览器访问域名为"api.baidu.com"或者"baidu.com"的时候携带 cookie,当url为"/"或者为"/home"..均携带 cookie。
secure 是保证网络请求安全的,如果设置 cookie 为secure,则发送的请求必须是 https 的。如果是 http 的请求,即使域名一样,也不会从浏览器携带到服务器。但是不携带并不代表没有,我们在浏览器上仍然可以查看到。
设置 cookie 的时候默认httpOnly为空。如果某条 cookie 设置了httpOnly,则 js 不能操作该条 cookie(查看,修改,删除)。
如果在某一个用户登录过的网站,其 cookie 没有设置httpOnly,则当用户受到 xss 攻击(跨站脚本攻击)的时候,也就是向该网站注入一段js脚本,如果这个脚本读取的是用户的 cookie,并且将该 cookie 发送给攻击者,则用户信息泄露,攻击者可以拿到该用户登录信息模拟用户登录,造成用户不安全。
允许服务器要求某个 cookie 在跨站请求时不会被发送,从而可以阻止跨站请求伪造攻击
cookie 有个特性就是如果设置了新 cookie(cookie的name和path都一样),则旧的 cookie 会被覆盖掉;否则,新的 Cookie 会被添加到 document.cookie,所以如果你想对cookie进行增加,修改和删除,都可以通过设置cookie函数实现,设置cookie函数如下:
function setCookies(name, value, expires, path) {
var date = new Date();
date.setTime(date.getTime() + expires * 24 * 60 * 60 * 3600);
document.cookie =
name + '=' + value + '; expires=' + date.toUTCString() + '; path=' + path;
}
读取 cookie 的函数只能获取指定 cookie 的value值,无法获取像超时时间和path等这样的信息,读取 cookie 的函数代码如下:
function getCookies(cname) {
var name = cname + '=';
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return '';
}

所谓的 WebStorage 指的是客户端存储,在这里指的是浏览器端存储,比如在网站上自动登陆这些功能,其实就是把一些少量的数据存储在浏览器等客户端中,这样可以减少没必要的请求到服务器,降低服务器的压力,给用户提供更好的体验.
WebStorage 的目的是克服由 cookie 所带来的一些限制,当数据需要被严格控制在客户端时,不需要持续的将数据发回服务器。
webstorage 两个主要目标:
生命周期:
存储大小:
localStorage 和 sessionStorage 的存储数据大小一般都是:5MB
存储位置:
都保存在客户端,不与服务器进行交互通信。
存储内容类型:
localStorage 和 sessionStorage 只能存储字符串类型,对于复杂的对象可以使用 ECMAScript 提供的 JSON 对象的 stringify 和 parse 来处理。
获取方式:
window.localStorage;window.sessionStorage。应用场景:
存储空间更大:
cookie 为4KB,而 WebStorage 是5MB;
节省网络流量:
WebStorage 不会传送到服务器,存储在本地的数据可以直接获取,也不会像cookie 一样每次请求都会传送到服务器,所以减少了客户端和服务器端的交互,节省了网络流量;
对于那种只需要在用户浏览一组页面期间保存而关闭浏览器后就可以丢弃的数据,sessionStorage 会非常方便;
快速显示:
有的数据存储在 WebStorage 上,再加上浏览器本身的缓存。获取数据时可以从本地获取会比从服务器端获取快得多,所以速度更快;
安全性:
WebStorage 不会随着 HTTP header 发送到服务器端,所以安全性相对于 cookie 来说比较高一些,不会担心截获,但是仍然存在伪造问题;
WebStorage 提供了一些方法,数据操作比 cookie 方便;
setItem (key, value) —— 保存数据,以键值对的方式储存信息。getItem (key) —— 获取数据,将键值传入,即可获取到对应的value值。removeItem (key) —— 删除单个数据,根据键值移除对应的信息。clear () —— 删除所有的数据key (index) —— 获取某个索引的key //设置localStorage保存到本地,第一个为变量名,第二个是值
localStorage.setItem('Author', 'Jane')
// 获取数据
localStorage.getItem('Author')
// 删除保存的数据
localStorage.removeItem('Author')
// 清除所有保存的数据
localStorage.clear()
首次使用localStorage时需要判断浏览器是否支持
if (!window.localStorage) {
alert('浏览器不支持localStorage');
return false;
} else {
//主逻辑业务
}
localStorage的读取和写入有三种方式
if (!window.localStorage) {
alert('浏览器不支持localStorage');
return false;
} else {
var storage = window.localStorage;
// 方法1
storage['a'] = 1;
console.log(storage.a);
// 方法2
storage.b = 2;
console.log(storage.getItem('b'));
// 方法3
storage.setItem('c', 3);
console.log(storage['c']);
}
// 设置sessionStorage保存到本地,第一个为变量名,第二个是值
sessionStorage.setItem('sessionName', 'John')
// 获取数据
sessionStorage.getItem('sessionName')
// 删除保存的数据
sessionStorage.removeItem('sessionName')
// 清除所有保存的数据
sessionStorage.clear()