Rodrick

vuePress-theme-reco Rodrick    2022
Rodrick Rodrick

Choose mode

  • dark
  • auto
  • light
Home
Category
  • CS基础
  • 数据库
  • 前端
  • 其他
Tag
About
Timeline
D&T
  • 官方文档

    • Vue
    • Vue3
    • Webpack
    • MDN
    • Node中文网
    • React
    • 小程序
    • FineReport
  • 学习面试

    • 现代JavaScript教程
    • ES6
    • 阿西河
    • LeetCode
    • 牛客网
  • 工具

    • bejson
Contact
  • Github
  • Gitee
author-avatar

Rodrick

62

Article

18

Tag

Home
Category
  • CS基础
  • 数据库
  • 前端
  • 其他
Tag
About
Timeline
D&T
  • 官方文档

    • Vue
    • Vue3
    • Webpack
    • MDN
    • Node中文网
    • React
    • 小程序
    • FineReport
  • 学习面试

    • 现代JavaScript教程
    • ES6
    • 阿西河
    • LeetCode
    • 牛客网
  • 工具

    • bejson
Contact
  • Github
  • Gitee
  • JS

    • ES6核心语法
    • 模块化&Webpack
    • Promise&异步函数async
    • WebSocket原理浅析
    • axios的使用
    • ES5的变量提升和ES6的暂时性死区
    • call、apply、bind的用法
    • 对象的原始值转换
    • 可选链"?."
    • 随机数方法
    • 深浅拷贝实现
    • Array常用处理
    • 防抖与节流
    • postMessage窗口间通讯
    • 解构赋值
    • Map&Set
    • 日期和时间
    • 对象属性
    • Toast组件简单封装
    • 原型链
    • 类 Class
    • Generator与异步迭代
    • 偏函数Partial和柯里化Currying
    • DOM操作
    • 事件处理
    • 事件循环EventLoop
    • 网络请求
    • 浏览器中存储数据
    • 正则表达式
  • CSS

  • 其他

浏览器中存储数据

vuePress-theme-reco Rodrick    2022

浏览器中存储数据

Rodrick 2020-12-13 js

# Cookie

# 使用

  • 使用 document.cookie 来获取 cookie

    cookie 的值是一些 name = value 的键值对构成,用分号 ; 隔开

  • cookie 的大小不能超过 4kb

  • 对 document.cookie  的写入操作只会更新其中提到的 cookie,而不会涉及其他 cookie:

document.cookie = "user=John"; // 只会更新名称为 user 的 cookie
alert(document.cookie); // 展示所有 cookie
  • 使用时应转码
// 特殊字符(空格),需要编码
let name = "my name";
let value = "John Smith"

// 将 cookie 编码为 my%20name=John%20Smith
document.cookie = encodeURIComponent(name) + '=' + encodeURIComponent(value);

alert(document.cookie); // ...; my%20name=John%20Smith

# 选项

我们在设置一个 cookie 的时候,可以给他加上一些选项,使得它有一些特别的属性,选项被列在 key=value  之后,以 ; 分隔,像这样:

document.cookie = "user=John; path=/; expires=Tue, 19 Jan 2038 03:14:07 GMT"
  • path=/mypath

如果一个 cookie 带有 path=/admin  设置,那么该 cookie 在 /admin  和 /admin/something  下都是可见的,但是在 /home  或 /adminpage  下不可见。

  • domain=site.com

默认的 cookie 无法从一个二级域 child.site.com 获得 site.com 的cookie,如果想要这样做,需要设置 domain=site.com 根域

  • expires/max-age —— 如果一个 cookie 没有设置这两个参数中的任何一个,那么在关闭浏览器之后,它就会消失。此类 cookie 被称为 "session cookie”。
    • expires=Tue, 19 Jan 2038 03:14:07 GMT 如果我们将 expires  设置为过去的时间,则 cookie 会被删除。
// 当前时间 +1 天
let date = new Date(Date.now() + 86400e3);
// 日期必须完全采用 GMT 时区的这种格式。
date = date.toUTCString();
document.cookie = "user=John; expires=" + date;
  • max-age=3600 —— cookie 的过期时间距离当前时间的秒数。
  • secure —— document.cookie = "user=John; secure";  使cookie 只能通过 HTTPS  传输
  • samesite —— 主要作用于防止 CSRF 攻击
    • samesite=strict 如果用户来自同一网站之外,那么设置了 samesite=strict  的 cookie 永远不会被发送。
    • samesite=lax 如果用户来自同一网站之外,但是满足
      1. HTTP 方法是安全的(例如 GET 方法,而不是 POST)。
      2. 该操作执行顶级导航(更改浏览器地址栏中的 URL[iframe 就不是顶级的])。

那么就会发送 cookie

# 获取删除和设置 Cookie 的封装

# 获取 Cookie

  1. 按位置获取
var username=document.cookie.split(";")[0].split("=")[1];
  1. 正则获取,为了方便理解这个正则,先给个常见的 document.cookie 返回的值格式【注意中间的空格】:

aa=qq; bb=ww; cc=123

//获取cookies
function getCookie(name){
    var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)");
    if(arr=document.cookie.match(reg)){
        return decodeURIComponent()(arr[2]);
    }else{
        return null;
    }
}

# 删除 Cookie

将 expires 时间设置为当前时间之前即可

function delCookie(name){
    var exp = new Date();
    exp.setTime(exp.getTime() - 1);
    var cval=getCookie(name);
    if(cval!=null){
        document.cookie= name + "="+cval+";expires="+exp.toGMTString();
    }
}

# 获取 Cookie

//设置cookies
function setCookie(name,value){
    var Days = 30;
    var exp = new Date();
    exp.setTime(exp.getTime() + Days*24*60*60*1000);
    document.cookie = name + "="+ encodeURIComponent(value) + ";expires=" + exp.toGMTString();
}

# LocalStorage 和 SessionStorage

# 概念

这两个 Web 存储对象可以在浏览器中存储数据,前者存于本地,后者存于浏览器标签页。

我们已经有了 cookie。为什么还要其他存储对象呢?

  • 与 cookie 不同,Web 存储对象不会随每个请求被发送到服务器。因此,我们可以保存更多数据。大多数浏览器都允许保存至少 2MB 的数据(或更多),并且具有用于配置数据的设置。
  • 还有一点和 cookie 不同,服务器无法通过 HTTP header 操纵存储对象。一切都是在 JavaScript 中完成的。
  • 存储绑定到源(域/协议/端口三者)。也就是说,不同协议或子域对应不同的存储对象,它们之间无法访问彼此数据。

# 方法

两个存储对象都提供相同的方法和属性:

  • setItem(key, value) —— 存储键/值对。
  • getItem(key) —— 按照键获取值。
  • removeItem(key) —— 删除键及其对应的值。
  • clear() —— 删除所有数据。
  • key(index) —— 获取该索引下的键名。
  • length —— 存储的内容的长度。

在遍历的时候,他们不可迭代,我们可以选择

  1. for(let i = 0; i < localStorage.length; i++)
  2. for(let key in localStorage)

但是他们都会输出内建字段,所以还可以选用 Object.keys(localStroage) 的方式来获取自己的 key

key 和 value 必须是字符串,对象建议用 JSON 存储

# storage 事件

他们俩的值被改变时,会触发 storage 事件,属性如下:

  • key —— 发生更改的数据的 key(如果调用的是 .clear() 方法,则为 null)。
  • oldValue —— 旧值(如果是新增数据,则为 null)。
  • newValue —— 新值(如果是删除数据,则为 null)。
  • url —— 发生数据更新的文档的 url。
  • storageArea —— 发生数据更新的 localStorage 或 sessionStorage 对象。
// 在其他文档对同一存储进行更新时触发
window.onstorage = event => { 
  if (event.key != 'now') return;
  alert(event.key + ':' + event.newValue + " at " + event.url);
};

localStorage.setItem('now', Date.now());

# IndexedDB

IndexedDB 是一个浏览器内置的数据库,由于暂时没有用到相关使用场景,没有了解,详见现代教程

欢迎来到 Rodrick
看板娘