作为一位前端er对cookie一定非常的熟悉,但是在项目中使用到的时候肯定少不了去面向google编程,去找一些cookie的用法,看一些API什么的。如果大家懒得去查一些API和对cookie的封装,一般会用js-cookie,今天就和大家一块学习下js-cookie到底做了什么,通过学习我们一定会收获不少知识的,本文没有什么高大上的技术,都是一些基础知识,相信每个人都能够理解并且用到项目当中去。接下来搬好小板凳,准备发车了。
git clone https://github.com/js-cookie/js-cookie.git cd js-cookie
首先官方大概介绍一下js-cookie和其优点:一个简单轻量的可以处理cookie的库,任何浏览器都适用,支持各种模块导入方式,还有一些使用方式:可以通过npm下载,也可以通过CDN引入。
// 设置cookie值 Cookies.set('name', 'value') // 设置过期时间 七天后过期 Cookies.set('name', 'value', { expires: 7 }) // 设置过期时间并且只对当前路径有效 Cookies.set('name', 'value', { expires: 7, path: '' }) // 获取设置的cookie Cookies.get('name') // 获取所有值 Cookies.get() // 获某个域名底下的值,如果没有定义,默认为当前文档位置的路径的域名部分 Cookies.get('name', { domain: 'sub.example.com' }) // 删除cookiee Cookies.remove('name')
name 设置或覆盖参数的名字(string)必须
value 设置参数值(string)必须
path 不填,默认当前文档位置的路径,必须为绝对路径,可选(string | null)
domain 不填,默认当前文档位置的路径的域名部分, 可选(string | null)不填,对话结束时过期,设置过期时间,可设置成过去的时间用于删除cookie,可选(Date.toUTCString())
secure 可会被https传输, 可选(boolean| null)
cookie 存储不太安全可被窃取,将它放在另一个域名或子域名之下,可利用同源策略保护不被读取,可以设置HttpOnly
首先把js-cookie源码拉取下来
git clone https://github.com/js-cookie/js-cookie.git
打开src文件可以看到三个js
├── api.mjs ├── assign.mjs └── converter.mjs
我们先打开api.mjs, 可以看到引入了其他两个文件, 和有一个init方法,传入了一些默认参数
我们可以先大概了解一下这些方法用来干什么的,init方法我们可以根据名字猜出来进行了初始化,可以看出返回了一个Object.create创建的对象,还有get和set方法我们也可以根据名字猜出来应该分别是设置存入cookie和读取cookie
我们可以看出init返回了一个新创建的对象
return Object.create( { set: set, // 设置cookie方法 get: get, // 读取cookie方法 remove: function (name, attributes) { // 删除cookie方法,其实内部调用了set方法,并把expirse设置为过去时间来删除 set( name, '', assign({}, attributes, { expires: -1 }) ) }, // 修改设置cookie的一些常用属性类似于path,domain,expires, 重新返回一个实例化的对象,可以设置一个全局的cookie共享设置的一些属性值 withAttributes: function (attributes) { return init(this.converter, assign({}, this.attributes, attributes)) }, // 和上个方法作用差不多,可以对converter,进行一些扩展 withConverter: function (converter) { return init(assign({}, this.converter, converter), this.attributes) } }, { // Object.create的可选值,新增一些对象上的属性, // Object.freeze冻结对象不能删除和修改另外不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值 attributes: { value: Object.freeze(defaultAttributes) }, converter: { value: Object.freeze(converter) } } )
set主要是存储cookie或者通过设置expires来删除cookie
function set (name, value, attributes) { // 没有document直接return 返回什么也不执行 if (typeof document === 'undefined') { return } // 把传入的值和默认值合并到一起,如果key一样,传入的值直接替换默认值 attributes = assign({}, defaultAttributes, attributes) // 如果传入expires为天数,时间则直接转换为毫秒 if (typeof attributes.expires === 'number') { attributes.expires = new Date(Date.now() + attributes.expires * 864e5) } // 把日期转为字符串设置cookie过期时间 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) { // 为空字符串或者null undefined退出本次循环 if (!attributes[attributeName]) { continue } stringifiedAttributes += '; ' + attributeName // 传入boolean值退出当前循环 if (attributes[attributeName] === true) { continue } stringifiedAttributes += '=' + attributes[attributeName].split(';')[0] } // 写入的时候使用converter进行encode编码 return (document.cookie = name + '=' + converter.write(value, name) + stringifiedAttributes) }
其关键通过接受传入的name和value值通过document.cookie设置cookie,对传入的其他属性attributes进行了遍历,例如:expires、domain、path,拼接成字符串写入cookie当中, 而且对过期时间进行处理转换,可以使用天数来传入过期时间,另外对name和value进行编码
get读取存入的cookie,如果没传入值直接返回一个所有存入cookie的对象,也可以使用正则匹配去读取cookie值
function get (name) { // 判断是否支持cookie if (typeof document === 'undefined' || (arguments.length && !name)) { return } // 获取到cookie,并把值切割成数组 var cookies = document.cookie ? document.cookie.split('; ') : [] var jar = {} for (var i = 0; i < cookies.length; i++) { // 字符串通过'='解析成数组 var parts = cookies[i].split('=') // 防止vuale存储的时候有等号, 在把name后的所有值拿出来加上等号 var value = parts.slice(1).join('=') try { // 解析name var found = decodeURIComponent(parts[0]) // 通过converter解析value值 jar[found] = converter.read(value, found) // 找到之后退出本次循环,节省内存 if (name === found) { break } } catch (e) {} } // 判断返回单独的一个值还是一个包含所有cookie值的对象 return name ? jar[name] : jar }
其关键通过接受传入的name读取cookie,对cookie的值进行遍历对比,如果一样直接退出循环并返回值,另外对name和value进行解码
js-cookie源码非常简短只有 100 行左右,源码简单易懂,建议自己动手看看。通过学习js-cookie源码自己又重新温故了一遍cookie的API还有Object.create和Object.freeze的API,还有encodeURIComponent和decodeURIComponent方法的使用。