本文详细解析JavaScript中Cookie与Web Storage的核心机制。涵盖Cookie的domain、path、expires等关键属性及其作用域规则,阐述localStorage与sessionStorage在存储大小、生命周期及共享范围上的差异,帮助开发者根据场景选择合适的数据存储方案。
Cookie基础与属性详解
Cookie
HTTP协议本身是无状态的,这意味着客户端与服务器完成数据交换并断开连接后,服务器无法仅凭网络连接识别用户身份。Cookie正是为了解决这一问题而诞生的机制。每次用户发起新请求时,服务器会颁发一个唯一的标识符(即Cookie)。后续访问时,客户端必须携带该标识符,服务器据此识别用户身份并提供差异化响应。Cookie是一个小型纯文本文件,最大容量为4KB,由浏览器存储在用户本地计算机上,用于保存服务器所需的信息。每次请求站点时,浏览器会自动发送相关的Cookie,从而实现用户身份识别等功能。
Cookie的属性字段
| props | intro |
|---|---|
| name | cookie的名称 |
| value | cookie的值 |
| domain | 可以访问cookie的域名 |
| path | 可以访问此cookie的页面路径 |
| expires/Max-Age | cookie有效的时间 |
| Size | cookie的大小 |
| httpOnly | js能否读取到cookie信息 |
| secure | 是否只能通过https来传递此条cookie |
Cookie以纯文本形式存储,其数据类型为String。
document.cookie = 'name=userInfo'; // 设置cookie的name属性
document.cookie = 'username=Jack'; // 在cookie中存储了username信息
console.log(document.cookie); // name=userInfo; username=Jack
document.cookie = 'name=userInfo'; // 设置cookie的name属性
document.cookie = 'username=Amy'; // 在cookie中存储了username信息
console.log(document.cookie); // name=userInfo; username=Amy
通过上述实例可知,直接给Cookie赋值不会覆盖原有值;只有当等号前的属性名相同时,新设置的值才会覆盖原有同名属性的值。需要注意的是,Cookie各字段之间通过分号和空格(; )进行分隔,而非仅使用分号。
当需要设置非自定义的Cookie属性字段时,需采用字符串追加的方式。
例如
let expireDate = new Date();
document.cookie += ";expires=" + expireDate.toString();
注意:在";expires="中,分号是必需的。如果字段前未添加分号,系统会将其识别为自定义字段而非标准属性。
domain
对于非顶级域名(如二级或三级域名),设置的Cookie的domain属性只能指定为顶级域名、二级域名或三级域名本身。若尝试设置为其他二级域名的Cookie,则无法生成。
顶级域名只能将domain设置为顶级域名本身,若设置为二级或三级域名,Cookie同样无法生成。
二级域名可以读取domain设置为顶级域名或自身的Cookie,但无法读取其他二级域名domain的Cookie。因此,若希望Cookie在多个二级域名间共享,需将domain设置为顶级域名,这样所有二级域名均可获取该Cookie的值。
顶级域名只能获取domain设置为顶级域名的Cookie,无法获取domain设置为二级域名的Cookie。
综上所述,上级域名无法访问下级域名的Cookie;下级域名可以读取自身及上级域名的Cookie;同级域名之间的Cookie不共享,即同级域名无法互相访问对方的Cookie,仅能访问自身的Cookie。
path
path字段定义了可以访问该Cookie的页面路径。例如,若domain为abc.com,path为/test,则只有/test路径下的页面可以读取此Cookie。
expires/Max-Age
expires/Max-Age字段定义了Cookie的超时时间。若设置为具体时间,到达该时间后Cookie失效。若不设置此字段,默认值为Session,即当整个浏览器关闭(注意:并非仅关闭标签页)时,Cookie失效。
let expireDate = new Date("2019-5-26T09:00:00");
document.cookie += ";expires=" + expireDate.toString();
若要删除某条Cookie,可将其expires设置为当前时间之前的时间点。
let expireDate = new Date("1970-01-01T00:00:00");
document.cookie += ";expires=" + expireDate.toString();
size
Size字段表示Cookie的大小。
httpOnly
若此属性设为true,则Cookie仅会在HTTP请求头中携带,无法通过document.cookie访问。设置为true可降低遭受XSS(跨站脚本攻击)的风险。
secure
secure字段用于设置是否仅能通过HTTPS协议传递该Cookie。
Web Storage机制与特性
localstorage/sessionstorage
Web Storage并非旨在替代Cookie,而是为了弥补随着Web发展,Cookie在存储限制(最大4KB)和安全性(HTTP协议中明文传输)方面的不足。
两者的API相同。
| function | intro |
|---|---|
| setItem(key, value) | 以键值对的形式保存一条数据 |
| getItem(key) | 根据键来获得值 |
| removeItem(key) | 根据键来删除一条数据 |
| key(index) | 根据索引获得键的名称 |
| clear() | 删除全部数据 |
两者均具有length属性。
sessionStorage.setItem("name", "Jack");
sessionStorage.setItem("phone", "18856894523");
console.log(sessionStorage.getItem('name')); // Jack
console.log(sessionStorage.key(0)); // name
console.log(sessionStorage.length); // 2
sessionStorage.removeItem('phone');
console.log(sessionStorage.length); // 1
sessionStorage.clear();
console.log(sessionStorage.length); // 0
两者的比较
- localStorage和sessionStorage均用于存储客户端临时信息,且只能存储字符串类型的对象。尽管规范允许存储其他原生类型对象,但目前主流浏览器尚未对此进行实现。
- localStorage的生命周期是永久的,除非用户通过浏览器提供的界面手动清除localStorage信息,否则这些数据将一直存在。
- sessionStorage的生命周期仅限于当前窗口或标签页。一旦窗口或标签页被永久关闭,sessionStorage存储的数据即被清空。
- 不同浏览器之间无法共享localStorage或sessionStorage中的信息。
- 相同浏览器的不同页面(属于相同域名和端口)之间可以共享相同的localStorage。
- 不同页面或标签页之间无法共享sessionStorage的信息。需要注意的是,页面及标签页仅指顶级窗口。如果一个标签页包含多个属于同源页面的iframe标签,它们之间可以共享sessionStorage。
- 使用window.open打开页面或通过改变location.href的方式,均可获取sessionStorage内部的数据。
Cookie与Web Storage对比
Cookie与Web Storage的区别
存储限制
- 每个domain中最多只能存储20条Cookie,且Cookie数据大小不能超过4KB。
- Web Storage也有存储大小限制,但比Cookie大得多,通常可达5MB或更大。
数据的有效期
- sessionStorage:仅在当前浏览器窗口关闭时有效;
- localStorage:始终有效,除非用户手动删除;
- Cookie:在Cookie过期时间之前一直有效,即使窗口和浏览器关闭。
作用域
- sessionStorage:不在不同的浏览器窗口中共享,即使是访问同一个页面;
- localStorage:同源窗口共享;
- Cookie:同源窗口共享。
总结
以上就是本文的全部内容,希望本文的内容对大家的学习或工作具有一定的参考借鉴价值,感谢支持。