手把手带你造 js-cookie 轮子
MIT License
https://github.com/Haixiang6123/my-js-cookie
Cookie Cookie npm MDN js-cookie js-cookie
Low get(key)``set(key, value)
del(key)
3 API
MDN API
document.cookie
a=1&b=2
document.cookie
Object key value
function get(key: string): string | null {
const cookiePairs = document.cookie ? document.cookie.split('; ') : []
const cookieStore: Record<string, string> = {}
cookiePairs.some(pair => {
const [curtKey, ...curtValues] = pair.split('=')
cookieStore[curtKey] = curtValues.join('=') // value '='
return curtKey === key // break
})
return key ? cookieStore[key] : null
}
cookie '=' split('=')
join('=')
a=123=456
join value 123=456
123
set add cookie
document.cookie = `${key}=${value}`
cookie key value expires path set
document.cookie = `${key}=${value}; expires=${expires}; path=${path}`
set key
, value
, attributes
3 attributes
cookie expires, path
interface Attributes {
path: string; // Cookie
expires?: string | number | Date // Cookie N
}
defaultAttributes
const TWENTY_FOUR_HOURS = 864e5
const defaultAttributes: Attributes = {path: '/'}
function set(key: string, value: string, attributes = defaultAttributes): string | null {
attributes = {...defaultAttributes, ...attributes}
if (attributes.expires) {
// UTC string
if (typeof attributes.expires === 'number') {
attributes.expires = new Date(Date.now() + attributes.expires * TWENTY_FOUR_HOURS)
attributes.expires = attributes.expires.toUTCString()
}
}
// Cookie "; expires=1; path=/"
const attrStr = Object.entries(attributes).reduce((prevStr, attrPair) => {
const [attrKey, attrValue] = attrPair
if (!attrValue) return prevStr
prevStr += `; ${attrKey}`
// attrValue truthy true
if (attrValue === true) return prevStr
// attrValue ";"
prevStr += `=${attrValue.split('; ')[0]}`
return prevStr
}, '')
return document.cookie = `${key}=${value}${attrStr}`
}
expires UTC attributes
string ${key}=${value}
** 864e5
24 Stackoverflow**
cookie set
expires -1
/**
* Cookie
*/
function del(key: string, attributes = defaultAttributes) {
// expires 1 Cookie
set(key, '', {...attributes, expires: -1})
}
cookie cookie cookie
cookie RFC 2109 RFC 2965 RFC6265
set get encodeURIComponent decodeURIComponent
function get(key: string): string | null {
...
cookiePairs.some(pair => {
const [curtKey, ...curtValue] = pair.split('=')
try {
//
const decodeedValue = decodeURIComponent(curtValue.join('=')) // value '='
cookieStore[curtKey] = decodeedValue
} catch (e) {}
return curtKey === key // break
})
return key ? cookieStore[key] : null
}
function set(key: string, value: string, attributes = defaultAttributes): string | null {
...
//
value = encodeURIComponent(value)
...
return document.cookie = `${key}=${value}${attrStr}`
}
so easy ~ encodeURIComponent
decodeURIComponent
defaultConverter
export interface Converter {
encode: (text: string) => string //
decode: (text: string) => string //
}
// Cookie
export const defaultConverter: Converter = {
encode(text: string) {
return text.replace(ASCII_HEX_REGEXP, encodeURIComponent)
},
decode(text: string) {
return text.replace(ASCII_HEX_REGEXP, decodeURIComponent)
},
}
set get
function get(key: string): string | null {
...
//
const decodeedValue = defaultConverter.decode(curtValue.join('=')) // value '='
...
}
function set(key: string, value: string, attributes = defaultAttributes): string | null {
...
//
value = defaultConverter.encode(value)
...
}
encodeURIComponent
decodeURIComponent
set
get
expires 1 set(xxx, yyy)
Cookie 1
//
Cookies.atributes = { expires: 1 }
Cookies.converter = {
encode(text: string) {
return "hello"
},
decode(text: string) {
return "world"
},
}
Cookies.set('aaa', 111) // 1 aaa="hello"
Cookies.set('bbb', 222) // 1 bbb="hello"
Cookies.get('aaa') // "world"
Cookies.get('bbb') // "world"
attributes converter
let customAttributes: Attributes = defaultAttributes
let customConverter: Converter = defaultConverter
function get(key: string): string | null {
...
const decodedValue = customConverter.decode(curtValue.join('=')) // value '='
...
}
/**
* Cookie key-val
*/
function set(key: string, value: string, attributes = defaultAttributes): string | null {
attributes = {...customAttributes, ...attributes}
...
value = customConverter.encode(value)
...
}
/**
* Cookie
*/
function del(key: string, attributes = defaultAttributes) {
// expires 1 Cookie
set(key, '', {...attributes, expires: -1})
}
const Cookies = {
get,
set,
del,
attributes: customAttributes,
converter: customConverter,
}
export default Cookies
attributes customAttributes
customCoverter
Cookies.attributes = {...Cookies.attributes, ...{ expires: 2 } }
...
function withAttributes(myAttributes: Attribute) {
customAttributes = {...customAttributes, ...myAttributes}
}
function withConverter(myConverter: Converter) {
customConverter = {...customConverter, ...myConverter}
}
const Cookies = {
get,
set,
del,
withAttributes,
withConverter
}
export default Cookies
customAttributes
customConverter
customAttributes
expires 3
function init(initConverter: Converter, initAttributes: Attributes) {
function get(key: string): string | null {
...
const decodeedValue = initConverter.decode(curtValue.join('='))
...
}
function set(key: string, value: string, attributes = customAttributes): string | null {
...
attributes = {...initAttributes, ...attributes}
value = initConverter.encode(value)
...
}
function del(key: string, attributes = customAttributes) {
set(key, '', {...attributes, expires: -1})
}
function withConverter(customConverter: Converter) {
return init({...this.converter, ...customConverter}, this.attributes)
}
function withAttributes(customAttributes: Attributes) {
return init(this.converter, {...this.attributes, ...customAttributes})
}
return {
get,
set,
del,
attributes: initAttributes,
converter: initConverter,
withAttributes,
withConverter
}
}
export default init(defaultConverter, defaultAttributes)
attributes
converter
withConverter``withAttributes
init
Cookies withXXX
const myCookies = Cookies.withAttributes({ expires: 2 }) //
attrCookies.set('aaa', 1) // 2
Coookies.set('aaa', 1) //
attributes
converter
Object.create
2 Object.freeze
atributes
converter
function init(initConverter: Converter, initAttributes: Attributes) {
...
return Object.create(
{get, set, del, withConverter, withAttributes},
{
converter: {value: Object.freeze(initConverter)}, //
attributes: {value: Object.freeze(initAttributes)}, //
}
)
}
export default init(defaultConverter, defaultAttributes)
Object.create
2 Object.defineProperties
Cookies.attributes = 1
console.log(Cookies.attributes) // {path: '/'} 1
js-cookie
init
document.cookie
Object key valueattributes
stringify key=value document.cookie = ${key}=${value}${attrStr}
set
expires -1 cookieattributes
converter
withAttributes
withConverter
init
Cookie
attributes
converter