js-cookie是一个javascript设置cookie的库,平时工作也有使用到。
1. 基本使用
1.1 设置cookie
函数包括三个参数
- name, 设置cookie的key
- value, 设置cookie的值
- attributes,设置属性expires过期时间等
Cookies.set('foo', 'bar')
Cookies.set('name', 'value', { expires: 7, path: '' })
1.2 获取cookie
参数name,获取cookie的key值
Cookies.get() // => { name: 'value' }
1.3 删除cookie
参数
- name,和get参数基本一致
- attributes?,设置属性(可以不需要,当set有其他属性就可加上)
Cookies.remove('name')
Cookies.set('name', 'value', { path: '' })
Cookies.remove('name') // fail!
Cookies.remove('name', { path: '' }) // removed!
2. 代码模块
2.1 set
原理是通过document.cookie = 'xxx'设置cookie,以;空格分隔的键值对
function set (name, value, attributes) {
if (typeof document === 'undefined') {
return
}
attributes = assign({}, defaultAttributes, attributes)
// 设置过期时间,或者默认,最后转为utc时区字符串
if (typeof attributes.expires === 'number') {
attributes.expires = new Date(Date.now() + attributes.expires * 864e5)
}
if (attributes.expires) {
attributes.expires = attributes.expires.toUTCString()
}
// 先进行转码再编码
name = encodeURIComponent(name)
.replace(/%(2[346B]|5E|60|7C)/g, decodeURIComponent)
.replace(/[()]/g, escape)
var stringifiedAttributes = ''
// 遍历属性并且放入字符串
for (var attributeName in attributes) {
if (!attributes[attributeName]) {
continue
}
stringifiedAttributes += '; ' + attributeName
if (attributes[attributeName] === true) {
continue
}
stringifiedAttributes += '=' + attributes[attributeName].split(';')[0]
}
return (document.cookie =
name + '=' + converter.write(value, name) + stringifiedAttributes)
}
2.2 get
原理是通过分割document.cookie成数组,遍历取返回值
function get (name) {
if (typeof document === 'undefined' || (arguments.length && !name)) {
return
}
// 分割出['xx=xxx']的数组
var cookies = document.cookie ? document.cookie.split('; ') : []
var jar = {}
// 遍历进行解码放进对象
for (var i = 0; i < cookies.length; i++) {
var parts = cookies[i].split('=')
var value = parts.slice(1).join('=')
try {
var found = decodeURIComponent(parts[0])
jar[found] = converter.read(value, found)
if (name === found) {
break
}
} catch (e) {}
}
return name ? jar[name] : jar
}
2.3 init方法
主入口函数
import assign from './assign.mjs'
import defaultConverter from './converter.mjs'
function init (converter, defaultAttributes) {
// ...set和get函数
return Object.create(
{
set: set,
get: get,
// 调用set方法并且设置expires: -1来执行
remove: function (name, attributes) {
set(
name,
'',
assign({}, attributes, {
expires: -1
})
)
},
// 设置默认自定义属性,之后设置cookie都会带上这些属性
withAttributes: function (attributes) {
return init(this.converter, assign({}, this.attributes, attributes))
},
// 设置默认解码器
withConverter: function (converter) {
return init(assign({}, this.converter, converter), this.attributes)
}
},
{
attributes: { value: Object.freeze(defaultAttributes) },
converter: { value: Object.freeze(converter) }
}
)
}
// 最后引入默认值
export default init(defaultConverter, { path: '/' })
withAttributes和withConverter官方例子
document.cookie = 'escaped=%u5317'
document.cookie = 'default=%E5%8C%97'
var cookies = Cookies.withConverter({
read: function (value, name) {
if (name === 'escaped') {
return unescape(value)
}
// Fall back to default for all other cookies
return Cookies.converter.read(value, name)
}
})
cookies.get('escaped') // 北
cookies.get('default') // 北
cookies.get() // { escaped: '北', default: '北' }
// ------
const api = Cookies.withAttributes({ path: '/', domain: '.example.com' })
##2.4 其余模块
assign.mjs
浅拷贝对象到新的对象
export default function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i]
for (var key in source) {
target[key] = source[key]
}
}
return target
}
converter.mjs
默认存在读写模块的对象
export default {
read: function (value) {
if (value[0] === '"') {
value = value.slice(1, -1)
}
// 解码
return value.replace(/(%[\dA-F]{2})+/gi, decodeURIComponent)
},
write: function (value) {
return encodeURIComponent(value).replace(
/%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g,
decodeURIComponent
)
}
}
3. 总结
js-cookie函数主要3个函数:
- set设置函数,会把过期时间进行设置为uTC时区时间,并且讲name先按照规则编码再解码,最后才写入
- get函数,会通过分号空格转换字符串为['xxx=xxx']数组,最后从遍历数组中获取值
- remove函数主要通过set函数设置过期时间为-1