js-cookie源码
js-cookie 源码
- 仓库地址
- 功能介绍:在浏览器上操作cookie的封装
- cookie知识
- 手动实现
根据cookie
的知识,我们可以把操作分为增删改查这几种操作,其中增删改都可以通过一个set
去实现,所以我们主要需要完成get
操作和set
操作,另外我们知道一个cookie
包括name
、value
、path
等属性,其中key
和value
为必须的,其他不是必须的,所以我们分隔下,其他属性当作attribute
- get(name?:string)
功能:当没有传入name
的时候全部返回,如果传入,判断是否在cookie
中,如果有就返回1
2
3
4
5
6
7
8
9
10
11function get(name) => {
let cookies = document?.cookie?.split(';') || []
let cookieStore = {}
cookies.some(cookie => {
const [found, ...valuesArr] = cookie.split("=")
const value = valuesArr.join("=") // 防止value存在=的情况
cookieStore[found] = value
return found === name
})
return name ? cookieStore[name] : cookieStore
} - set(name:string, value:string, attributes: Record<string,any>)
功能:根据传入设置cookie
1
2
3
4
5
6
7
8
9
10
11function set(name, value, attributes) {
let attributesOfString = Object.entries(attributes).reduce((preString, nextPreAttribute)=> {
const [name, value] = nextPreAttribute
if(!value) return preString
preString += `; ${name}`
if(value === true) return preString
preString += `=${value.split(';')[0]}` // 防止value有;的情况
},'')
return (document.cookie = `${name}=${value};${attributesOfString}`)
} - 其他操作:
remove:1
2
3set( name, '', {
expires: -1
}) - 基本功能到此就结束了
- get(name?:string)
- 对比源码
- 在
attribute
中添加默认对象,并提供withAttributes
修改默认对象 - 提供
withConverter
,提供自定义转换器,用于转换生成的cookie及查到的cookie - 代码上主要对比整体上代码对比
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37const converter = { // 默认的转换器
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
)
}
}
function set() {
//...
attributes = assign({}, defaultAttributes, attributes) //合并默认
if (typeof attributes.expires === 'number') { // 把传入的时间数字格式化为时间对象
attributes.expires = new Date(Date.now() + attributes.expires * 864e5) // 864e5 为一天
}
if (attributes.expires) {
attributes.expires = attributes.expires.toUTCString() // 统一格式化为标准时间字符串
}
name = encodeURIComponent(name) // 对 name 编码,防止不能处理的情况
.replace(/%(2[346B]|5E|60|7C)/g, decodeURIComponent)
.replace(/[()]/g, escape)
//...
return (document.cookie =
name + '=' + converter.write(value, name) + stringifiedAttributes) // converter 为 传入的转换器,返回字符串
}
function get(name) {
//...
var found = decodeURIComponent(parts[0]) // 解码 name
//...
}每次修改配置,都会返回一个新的操作1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28import assign from './assign.mjs' // 合并函数
import defaultConverter from './converter.mjs' // 获取默认转换器
function init(converter, defaultAttributes) {
function set (name, value, attributes) {
//...
}
function get (name) {
//...
}
return Object.create({
set: set,
get: get,
remove: function (name, attributes) {
set(name, '', assign({}, attributes, {expires: -1}))
},
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: '/'})cookie
的对象
- 在
总结
- js-cookie中返回的对象中,包括了
get
获取cookieset
设置cookieremove
删除cookiewithAttributes
更新默认配置withConverter
更新默认转换器
- 通过返回的方法去操作内部的方法,利用闭包对操作进行了隔离,防止使用者对内部函数覆盖,也防止了内部函数污染全局