cookie通常用于会话状态管理(登录标识),个性化配置信息,埋点信息收集(uuid).
目前浏览器端cookie API使用很不方便,需要封装一个易用的cookie.js库:
const cookie = {
set(name, value, options = {}, env = '') {
if (env) name = `${env}_${name}`;
if (typeof options.expires === 'number') {
let days = options.expires;
let t = options.expires = new Date();
t.setMilliseconds(t.getMilliseconds() + days * 864e+5);
}
// const {expires, path, domain, secure} = options;
return document.cookie = [
`${name}=${value}`,
options.expires ? `; expires=${options.expires.toUTCString()}` : '',
options.path ? `; path=${options.path}` : '',
options.domain ? `; domain=${options.domain}` : '',
options.secure ? `; secure` : '',
].join('');
},
get(name, env = '') {
if (name && env) name = `${env}_${name}`;
const cookies = document.cookie ? document.cookie.split('; ') : [];
const len = cookies.length;
let ret = name ? '' : Object.create(null);
for (let i=0; i < len; i++) {
const [key, value] = cookies[i].split('=');
if (key === name) {
ret = value;
break;
}
if (!name) ret[key] = value;
}
return ret;
},
del(name, config = {}, env = '') {
this.set(name, '', Object.assign({}, config, {expires: -1}), env);
return !this.get(name, env);
}
};
export default cookie;复制代码
- get()不传参数,返回全部cookies对象,如一次性读取多个cookie场景
- env参数可支持不同开发环境(beta/prod/dev)设置,当设置父域时可避免影响测试
- name和value因需要通过HTTP传输,不能包含一些特殊字符,详见API说明
cookie API
cookies = document.cookie
获取所有目前域下可访问的cookies. "name1=value1; name2=value2; ....",注意;后有空格符.子域可访问父域.
document.cookie = "name=value{; expires=GMT date string}..."
客户端设置单个cookie.
* name: 除了控制字符,空格或制表符之外的任何 US-ASCII 字符。同时不能包含以下分隔字符: () <> @ , ; : \ " / [ ] ? = { }.
* value: 需要包含在双引号里面,除了控制字符,空格,双引号,逗号,分号以及反斜线之外的任意ASCII 字符.可用encodeURIComponent()编码
* expires?: GMT date string,不设置表示一个会话cookie
* max-age?: cookie失效之前经历的秒数,相对于客户端计算.其优先级大于expires. (可从HTTP cache control设置/版本发展来理解.IE 6-8不支持
* domain?: 设置主机名.不设默认表示当前主机名,有父子域概念. (类似JavaScript作用域
* path?: 设置url路劲.不设默认当前path(/),有上下级目录访问概念,同JavaScript作用域概念
* secure?: secure标识该cookie只通过https传输,http下不传输
cookie类别
会话cookie
未设置过期时间,浏览器关闭后就清掉.
持久性cookie
指定了一个过期时间,设置的时间只与客户端有关.
第三方cookie
cookie作用域与当前页面域不同.请求CORS API,会将CORS API域下设置的cookies信息发送给对应服务端.常用于广告跟踪, 大型网站SSO登录等.
iframe限制,safari,ie<9, CSP策略.
notice
* 每次请求服务端,http <=1.1都会携带cookie信息给服务端,会有性能开销,因此与服务端没有交互的数据建议使用storage API储存.HTTP 2.0的头部压缩对此有优化,静态资源部署CDN可减少主域的cookie传输.
* domain设置父域时,前面无需带.
* 浏览器可设置cookie可用性.(navigator.cookieEnabled可判断
* 服务器端可设置httpOnly字段限制客户端JavaScript访问修改
* 只想简单读取单个cookie,可使用正则匹配
let match = document.cookie.match(new RegExp('(^|;\\s*)(' + name + ')=([^;]*)'));
let value = (match ? decodeURIComponent(match[3]) : null);复制代码
文章推荐
developer.mozilla.org/zh-CN/docs/…
developer.mozilla.org/zh-CN/docs/…