cookie是什么
HTTP 是无状态的协议,这方便了它的扩展,但也会造成一些问题:因为它的每个请求都是完全独立的,,前一秒发送的请求,后一秒就完全不知道你是谁了。
既然服务器记不住,那就在外部想办法记住,HTTP 的 Cookie 就是为了解决这一问题的机制,你可以理解为是服务器给每个客户端都贴上一张小纸条,上面写了一些只有服务器才能理解的数据,需要的时候客户端把这些信息发给服务器,服务器看到 Cookie,就能够认出对方是谁了。
使用 js-cookie 解决了什么问题?
适用于所有浏览器
接受任何字符
经过严格测试
无依赖关系
支持ES模块
支持AMD/CommonJS
符合RFC 6265
有用的Wiki
启用自定义编码/解码
<800字节gzip!
同时相对于原生方法更加优雅
// 原生 ==========
// 修改
document.cookie = "name=qingfeng"; // 只会更新名称为 user 的 cookie
document.cookie = "name=qingfeng123"
// 删除
// 删除 cookie(让它立即过期)
document.cookie = "expires=Thu, 01 Jan 1970 00:00:00 GMT";
document.cookie = "=qingfeng; max-age=0";
// js-cookie ===============
// set
Cookies.set('name', 'value')
// get
Cookies.get('name') // => 'value'
Cookies.get() // => { name: 'value' }
// remove
Cookies.remove('name')
阅读源码
"exports": {
".": {
"import": "./dist/js.cookie.mjs",
"require": "./dist/js.cookie.js"
},
"./package.json": "./package.json"
},
打包查看入口文件,当然我们这里直接去src 目录下查看 api.mjs 文件
.mjs 后缀第一次遇见,那什么是.mjs呢?
.mjs
.mjs:表示当前文件用 ESM 的方式进行加载
.js :采用 CJS 的方式加载。
api.mjs文件有什么呢?
1、引用工具方法 assign 和 defaultConverter
2、核心逻辑 INIT 函数
init 接受两个参数,一个转换器,一个默认对象
init函数内部实现
init方法内部,定义了set,get方法,并返回了一个使用Object.create方法创建的对象
1、set ----> 作用是写入COOKIE
function set(name, value, attributes) {
// document 不存在时直接返回
if (typeof document === 'undefined') {
return
}
// 合并 set attributes 和 init defaultAttributes
attributes = assign({}, defaultAttributes, attributes)
// 判断过期时间是否是数字类型
if (typeof attributes.expires === 'number') {
// 转毫秒
attributes.expires = new Date(Date.now() + attributes.expires * 864e5)
}
if (attributes.expires) {
// 转UTC,UTC和GMT,它们都是指的格林尼治标准时间,
// 只不过UTC的称呼更为正式一点。两者的区别在于前者是一个天文上的概念而后者是基于一个原子钟。
attributes.expires = attributes.expires.toUTCString()
}
// 使用decodeURIComponent对名称进行处理
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
}
// Considers RFC 6265 section 5.2:
// ...
// 3. If the remaining unparsed-attributes contains a %x3B (";")
// character:
// Consume the characters of the unparsed-attributes up to,
// not including, the first %x3B (";") character.
// ...
// 拼接值
stringifiedAttributes += '=' + attributes[attributeName].split(';')[0]
}
// 使用document.cookie赋值COOKIE
return (document.cookie =
name + '=' + converter.write(value, name) + stringifiedAttributes)
}
2、get ----> 作用是读取COOKIE
function get(name) {
// document arguments,名称不存在时,直接返回
if (typeof document === 'undefined' || (arguments.length && !name)) {
return
}
// To prevent the for loop in the first place assign an empty array
// in case there are no cookies at all.
// cookies存在分号截取,否则返回空数组
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) {}
}
// 有name 返回当前name对应value,没有返回所有
return name ? jar[name] : jar
}
相对而言,get逻辑要简单一些,主要是对数据读取并返回键值对
3、return 返回
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)
}
})
返回set,get,remove 方法,remove就是将当前name值过期时间设置为-1.withAttributes和withConverter则把自己的属性和传入的参数进行合并
4、assign方法
/* eslint-disable no-var */
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
}
/* eslint-enable no-var */
拷贝合并
5、defaultConverter
/* eslint-disable no-var */
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
)
}
}
/* eslint-enable no-var */
导出read,write方法
这样一来整个js-cookie就完成了~
总结思考
为什么会出现cookie
cookie 和 session token 区别
cookie和localstorage和sessionstorage的区别
js-cookie 有什么优势,为什么要引入呢?