- 都会在浏览器端保存,有大小限制,同源限制
- cookie:如果没有设置有效期则关闭浏览器就清除;适用于验证登录状态;cookie设置secure时要求HTTPS传输
document.cookie="username=John Doe; expires=Thu, 18 Dec 2043 12:00:00 GMT; path=/";
有效期:非常短暂,存在于web浏览器会话期间,当浏览器关闭,cookie也就消失了。如果要延长cookie的有效期,可以设置max-age属性(单位秒)
作用域:通过domain和path决定。默认和创建它的web页面有关,该web页面同目录或者子目录页面可见。当设置path="/",它的作用域就变成文档源级别的了。
-
sessionStorage:标签页关闭就清除;数据存储;针对一个session的数据存储
有效期:窗口或者标签页被永久关闭,存储的数据也就失效了。
作用域:文档源级别,⚠️通过点击链接(或者用了
window.open
)打开的新标签页之间是属于同一个 session 的,但新开一个标签页总是会初始化一个新的 session,即使网站是一样的,它们也不属于同一个 session。
this.queryParams={name:this.insuredOneName,id:this.insuredOneID};
sessionStorage.setItem('queryParam',JSON.stringify(this.queryParams))
-
localStorage:永久保存,除非手动清除;数据存储;存储js文件,第一次访问页面时加载,以后访问时直接加载本地localStorage
有效期:永不失效,除非web应用主动删除。
作用域:localStorage的作用域是限定在文档源级别的。文档源通过协议、主机名以及端口三者来确定。
localStorage.setItem("key", "value");
var lastname = localStorage.getItem("key");
localStorage.removeItem("key");
cookie和session的区别
session
是在服务器端程序运行的过程中创建的,不同语言实现的应用程序有不同创建Session的方法,而在Java中是通过调用HttpServletRequest的getSession方法(使用true作为参数)创建的。在创建了Session的同时,服务器会为该Session生成唯一的Session id,而这个Session id在随后的请求中会被用来重新获得已经创建的Session;在Session被创建之后,就可以调用Session相关的方法往Session中增加内容了,而这些内容只会保存在服务器中,发到客户端的只有Session id;当客户端再次发送请求的时候,会将这个Session id带上,服务器接受到请求之后就会依据Session id找到相应的Session,从而再次使用之。正式这样一个过程,用户的状态也就得以保持了。
session的时效性:Session在用户第一次访问服务器的时候自动创建。Session生成后,只要用户继续访问,服务器就会更新Session的最后访问时间,并维护该Session,如果超过了超时时间没访问过服务器,Session就自动失效了。
Cookie和Session的方案虽然分别属于客户端和服务端,但是服务端的session的实现对客户端的cookie有依赖关系的,上面我讲到服务端执行session机制时候会生成session的id值,这个id值会发送给客户端,客户端每次请求都会把这个id值放到http请求的头部发送给服务端,而这个id值在客户端会保存下来,保存的容器就是cookie,因此当我们完全禁掉浏览器的cookie的时候,服务端的session也会不能正常使用
新开的浏览器窗口会生成新的Session,但子窗口除外。子窗口会共用父窗口的Session。
关系登录访问下次继续访问时
Unicode编码:保存中文
中文与英文字符不同,中文属于Unicode字符,在内存中占4个字符,而英文属于ASCII字符,内存中只占2个字节。Cookie中使用Unicode字符时需要对Unicode字符进行编码,否则会乱码。
Cookie的安全属性
HTTP协议不仅是无状态的,而且是不安全的。使用HTTP协议的数据不经过任何加密就直接在网络上传播,有被截获的可能。使用HTTP协议传输很机密的内容是一种隐患。如果不希望Cookie在HTTP等非安全协议中传输,可以设置Cookie的secure属性为true。浏览器只会在HTTPS和SSL等安全协议中传输此类Cookie。下面的代码设置secure属性为true:
Cookie cookie = new Cookie("time", "20080808"); // 新建Cookie
cookie.setSecure(true); // 设置安全属性
response.addCookie(cookie); // 输出到客户端
W3C标准的浏览器会阻止JavaScript读写任何不属于自己网站的Cookie。换句话说,A网站的JavaScript程序读写B网站的Cookie不会有任何结果。
如何设计过期时间的localStorage
⚠️localStorage存进去时将对象转为json字符串,取出来是string
- 存入数据时,加上一个时间戳expire,并且记录存入时间:time: Date.now()得到的是一串数字。
- 读取数据时,先得到当前时间:Date.now(),做if判断: if (Date.now() - val.time > val.expire)
- 如果结果为真,说明存储超时,则立即删除:localStorage.removeItem(key);并返回空null,否则返回数据:val.data
class Storage {
constructor(props) {
this.props = props || {}
this.source = this.props.source || window.localStorage
this.initRun();
}
initRun(){
/*
* set 存储方法
* @ param {String} key 键
* @ param {String} value 值,存储的值可能是数组/对象,不能直接存储,需要转换 JSON.stringify
* @ param {String} expired 过期时间,以分钟为单位
*/
const reg = new RegExp("__expires__");
let data = this.source;
let list = Object.keys(data);
if(list.length > 0){
list.map((key,v)=>{
if( !reg.test(key )){
let now = Date.now();
let expires = data[`${key}__expires__`]||Date.now+1;
if (now >= expires ) {
this.remove(key);
};
};
return key;
});
};
}
set(key, value, expired) {
/*
* set 存储方法
* @ param {String} key 键
* @ param {String} value 值,
* @ param {String} expired 过期时间,以毫秒为单位,非必须
*/
let source = this.source;
source[key] = JSON.stringify(value);
if (expired){
source[`${key}__expires__`] = Date.now() + expired
};
return value;
}
get(key) {
/*
* get 获取方法
* @ param {String} key 键
* @ param {String} expired 存储时为非必须字段,所以有可能取不到,默认为 Date.now+1
*/
const source = this.source,
expired = source[`${key}__expires__`]||Date.now+1;
const now = Date.now();
if ( now >= expired ) {
this.remove(key);
return;
}
const value = source[key] ? JSON.parse(source[key]) : source[key];
return value;
}
remove(key) {
const data = this.source,
value = data[key];
delete data[key];
delete data[`${key}__expires__`];
return value;
}
}