众所可能周知,微信小程序是不支持 cookie 的,这就非常影响前后端的沟通,所以不得不自己实现一套 cookie 机制了。

使用方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import cookie from '../plugins/cookie.js';

cookie.getAllString() // 获取cookie字符串
cookie.get('key') // 获取某个cookie值
cookie.set('key', 'value') // 设置一个新的cookie值
cookie.delete('key') //删除某个cookie值
cookie.clear() // 清空cookie

// 在http请求头部的使用:设置请求中的cookie值
opt.header = Object.assign(opt.header || {}, {
Cookie: cookieUtil.getAllString(),
});

// 在http请求回调的使用:设置回调中的cookie值
const setCookieStr = res.header['Set-Cookie'] || res.header['set-cookie'];
setCookieStr && cookie.parseSetCookie(setCookieStr);
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/**
* 利用 storage 模拟 cookie 操作
* 请求等情况下数据要求较高,所以需要同步操作
* cookie 存储格式:{ key: { value: 'value', expires: 1526452752000 } }
*/

const storageKey = 'reqCookie';

const Fn = {
// 获取 cookie 字符串
getAllString() {
const cookie = this._getAll();
const deleteArr = [];
const result = [];
Object.keys(cookie).forEach(key => {
if (typeof cookie[key] !== 'object' || this._checkExpires(cookie[key]) || !cookie[key].value) {
deleteArr.push(key);
} else {
result.push(`${key}=${cookie[key].value}`);
}
});
this.batchDelete(deleteArr);
return result.join('; ');
},

// 获取 cookie 中一个字段
get(key) {
if (!key) return;

const cookie = this._getAll();
if (this._checkExpires(cookie[key]) || typeof cookie[key] !== 'object') {
this.delete(key);
}
return cookie[key] && cookie[key].value;
},

// 设置 cookie 中一个字段
set(key, value) {
if (!key) return false;

try {
const cookie = this._getAll();
cookie[key] = typeof value === 'object' ? value : { value };
wx.setStorageSync(storageKey, JSON.stringify(cookie));
return true;
} catch (e) {
console.error(e); // eslint-disable-line
return false;
}
},

// 设置 cookie 多个字段
batchSet(obj) {
if (!obj || typeof obj !== 'object') return false;

try {
const cookie = this._getAll();
Object.keys(obj).forEach(key => {
obj[key] = typeof obj[key] === 'object' ? obj[key] : { value: obj[key] };
});
Object.assign(cookie, obj);
wx.setStorageSync(storageKey, JSON.stringify(cookie));
return true;
} catch (e) {
console.error(e); // eslint-disable-line
return false;
}
},

// 删除 cookie 中一个字段
delete(key) {
if (!key) return false;

try {
const cookie = this._getAll();
cookie[key] && (delete cookie[key]); // eslint-disable-line
wx.setStorageSync(storageKey, JSON.stringify(cookie));
return true;
} catch (e) {
console.error(e); // eslint-disable-line
return false;
}
},

// 删除 cookie 多个字段
batchDelete(keyArr) {
if (!keyArr || !keyArr.length) return false;

try {
const cookie = this._getAll();
keyArr.forEach(key => {
cookie[key] && (delete cookie[key]); // eslint-disable-line
});
wx.setStorageSync(storageKey, JSON.stringify(cookie));
return true;
} catch (e) {
console.error(e); // eslint-disable-line
return false;
}
},

// 清除 cookie
clear() {
try {
wx.setStorageSync(storageKey, '{}');
return true;
} catch (e) {
console.error(e); // eslint-disable-line
return false;
}
},

// 解析 set-cookie
parseSetCookie(str) {
if (!str) return;

const expiresReg = /expires=([^;]+);/gi;
const setCookieStr = str.replace(expiresReg, (match, time) => `expires=${new Date(time).getTime()};`).replace(/\s+/gi, '');
const cookieObj = {};
setCookieStr.split(',').forEach(cookieStr => {
let key;
cookieStr.split(';').forEach((part, index) => {
try {
const cArr = part.split('=');
if (index === 0) {
key = cArr[0];
cookieObj[key] = { value: cArr[1] };
} else if (cArr[0] === 'expires') {
cookieObj[key].expires = cArr[1];
}
} catch (e) {
console.error(e); // eslint-disable-line
}
});
});
this.batchSet(cookieObj);
},

// 检查 cookie 是否过期
_checkExpires(valueObj) {
return valueObj && valueObj.expires && Date.now() > valueObj.expires;
},

// 获取 cookie 对象
_getAll() {
let cookie = {};
try {
const storage = wx.getStorageSync(storageKey);
cookie = storage ? JSON.parse(storage) : {};
} catch (e) {
console.error(e); // eslint-disable-line
}
return cookie;
},
};

export default Fn;