# Cookie
# 使用
使用
document.cookie
来获取 cookiecookie 的值是一些
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
如果用户来自同一网站之外,但是满足- HTTP 方法是安全的(例如 GET 方法,而不是 POST)。
- 该操作执行顶级导航(更改浏览器地址栏中的 URL[iframe 就不是顶级的])。
那么就会发送 cookie
# 获取删除和设置 Cookie 的封装
# 获取 Cookie
- 按位置获取
var username=document.cookie.split(";")[0].split("=")[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
—— 存储的内容的长度。
在遍历的时候,他们不可迭代,我们可以选择
for(let i = 0; i < localStorage.length; i++)
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
是一个浏览器内置的数据库,由于暂时没有用到相关使用场景,没有了解,详见现代教程