作用:中文/二进制 url编码/解码
/* eslint-disable no-var */
// 模块功能:url编码/解码
// 1-JS全局函数
/**
函数名称:encodeURIComponent(uri)
函数功能:把字符串作为 URI 组件进行编码
参数:uri 必须,一个字符串,含有 URI 组件或其他要编码的文本
返回值:URI字符串
说明:该方法不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码: - _ . ! ~ * ' ( )
*/
/**
函数名称:decodeURIComponent(uri)
函数功能:对 encodeURIComponent() 函数编码的 URI 进行解码
参数:uri 必需,一个字符串,含有编码 URI 组件或其他要解码的文本
说明:编码特点 %[\dA-F]{2}
*/
// 2-url构成
/**
网页地址实例: http://www.runoob.com/html/html-tutorial.html
语法规则: scheme://host.domain:port/path/filename
scheme:因特网服务的类型。最常见的类型是 http
host:域主机(http 的默认主机是 www)
domain:因特网域名,比如 runoob.com
:port:主机上的端口号(http 的默认端口号是 80)
path:服务器上的路径(如果省略,则文档必须位于网站的根目录中)
filename:文档/资源的名称
*/
export default {
/**
函数名称:converter.read(value)
函数功能:uri解码
参数:value 必需,要取得的Cookie名称
说明:
*/
read: function (value) {
if (value[0] === '"') {
value = value.slice(1, -1)
}
return value.replace(/(%[\dA-F]{2})+/gi, decodeURIComponent)
},
/**
函数名称:converter.write(value)
函数功能:uri编码
参数:value 必需
说明:
*/
write: function (value) {
return encodeURIComponent(value).replace(
/%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g,
decodeURIComponent
)
}
}
/* eslint-enable no-var */
作用:分割 Cookie 键值对字符串
/* eslint-disable no-var */
/**
函数名称:function (target)
函数功能:Cookie字符串分割
参数:target 必需,要分割的Cookie名称
返回值:target[key]
说明:浅层遍历args,并分别返回各参数
*/
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 */
作用:定义 cookie 功能函数
/* eslint-disable no-var */
import assign from './assign.mjs'
import defaultConverter from './converter.mjs'
// 1-知识点Cookie -4B
/**
属性:Cookie 是不可以跨域名
name:
value:
Expires: 有效期,单位s;
domain: 域名,解决跨域问题。Cookie是不可以跨域名的;
path: 允许访问Cookie的路径,默认情况下,cookie 属于当前页面。
数据存储格式:Cookie 以名/值对形式存储 *字符串*
示例:username=John Doe; expires=Thu, 18 Dec 2043 12:00:00 GMT; path=/
存储/获取:document.cookie
返回格式: 字符串
cookie总结:
cookie 在过期时间之前一直有效,即使窗口或浏览器关闭
浏览器也会在每次请求的时候 *主动组织* 所有域下的cookie到请求头 cookie 中,发送给服务器端
浏览器会 *主动存储* 接收到的 set-cookie 头信息的值
可以设置 http-only 属性为 true来禁止客户端代码(js)修改该值
可以设置有效期 (默认浏览器关闭自动销毁)(不同浏览器有所不同)
同域下个数有限制,最好不要超过50个(不同浏览器有所不同)
单个cookie内容大小有限制,最好不要超过4000字节(不同浏览器有所不同)
应用场景:
保存用户登录状态;
跟踪用户行为。如:购物车
*/
// 2-知识点Storage -5MB
/**
localStorage:*永久存储* 在本地硬盘的数据中,生命周期是永久(除非手动删除)
属性:
key:
value:
数据存储格式:*字符串* (auto)
<script>
localStorage.setItem('name', '张三')
localStorage.age = 18
localStorage['sex'] = '男'
localStorage.obj = JSON.stringify({ name: '小明' })
console.log(localStorage.name) //张三
console.log(localStorage.getItem('age')); //18
console.log(localStorage['sex']) //男
console.log(JSON.parse(localStorage.obj)) //{name: "小明"}
localStorage.removeItem('age')
console.log(localStorage.age); //undefined
console.log(localStorage.key(0)); //obj
console.log(localStorage.key(1)); //name
console.log(localStorage.key(2)); //sex
// window.localStorage.clear()
// console.log(localStorage); //Storage {length: 0}
</script>
sessionStorage:*临时存储* 在浏览器中,生命周期为浏览器页面打开时间(页面关闭时数据丢失)
属性:
key:
value:
数据存储格式:*字符串* (auto)
两者通用属性和方法:
setItem(keyname,value) 存储键值对,如果键名相同,则更新值
getItem(keyname) 根据键名查找对应的值
key(n) 返回第n个键的名称
length 返回键键值对的数量(存储了几个不同的数据)
removeitem(keyname) 根据键名删除对应的键值对
clear() 清除所有键
*/
// 2-init 方法 初始化
function init (converter, defaultAttributes) {
/**
函数名称:set (name, value, attributes)
函数功能:保存Cookie
参数:attributes 可选项,格式为对象
返回值:
说明:
*/
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
}
// 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]
}
// 写入的时候使用converter进行encode编码
return (document.cookie =
name + '=' + converter.write(value, name) + stringifiedAttributes)
}
// get 方法 读取cookie
function get (name) {
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.
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
}
// 返回 新创建的对象
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) }
}
)
}
export default init(defaultConverter, { path: '/' })
/* eslint-enable no-var */