在调用wx.request后,得到的 res.header['Set-Cookie'] 是类似如下的格式:
****=****:max-age=31536000; expires=Tue, 06-Aug-19 09:29:39 GMT; domain=****; path=/,****=****,****=****; path=/,****=****; path=/; domain=****; expires=Thu, 01 Jan 1970 00:00:00 GMT,****=****; max-age=3600; domain=****; path=/
但原本应是以下格式:
Set-Cookie: ****=****:max-age=31536000; expires=Tue, 06-Aug-19 09:29:39 GMT; domain=****; path=/
Set-Cookie: ****=****
Set-Cookie: ****=****; path=/
Set-Cookie: ****=****; path=/; domain=****; expires=Thu, 01 Jan 1970 00:00:00 GMT
Set-Cookie: ****=****; max-age=3600; domain=****; path=/
也就是说,在响应头中有多个Set-Cookie时,微信返回的Set-Cookie是把所有的值以逗号相连后返回的。
这样就带来了一个很棘手的问题,也就是说,当Set-Cookie中含有逗号时(在expires中就必然有一个逗号),再用逗号连接多个Set-Cookie值时就会产生分割困难的问题。对于这样的问题,是否有一个比较好的解决方法。官方是否可以改进下,不要再以逗号分隔,而是以数组形式返回,以防止出现类似的分割困难。
反馈已收到,我们考虑一下。
开发者工具中可在wx.request的返回值res中通过res.header.cookies取到包含多个cookie字符串的数组。但是在真机中res.header.cookies字段为空。
通过抓包看到响应是包含多个set-cookie字段的。小程序返回的结果如题主所述。
自己写了两个函数暂时解决一下该问题。代码如下,希望帮到后面碰到问题的人。 P.S. 这个方法无法兼容服务器端传回的cookie的值中包含有逗号的场景
/**
* 解析多个cookie的字符串
*/
parse:
function
(string) {
const list = (string ||
''
).split(
','
);
const result = [];
list.forEach(i => {
// 合并非分隔符的数据
if
(i.startsWith(
' '
)) {
if
(result.length > 0) {
result[result.length - 1] = result[result.length - 1] + i;
}
else
{
result.push(i);
}
}
else
{
result.push(i);
}
});
return
result.map(i =>
this
.parseOne(i));
},
/**
* 解析单个cookie的字符串
*/
parseOne:
function
(string, path, domain) {
var
s = string.replace(/;\s+/g,
';'
).split(
';'
)
.map(
function
(s) {
return
s.replace(/\s+\s+/g,
'='
).split(
'='
); });
var
n = s.shift();
var
obj = {};
obj.expires =
false
;
obj.httponly =
false
;
obj.secure =
false
;
obj.path = path ||
'/'
;
obj.domain = domain ||
''
;
var
I, f = {
httponly:
function
() { obj.httponly =
true
; },
secure:
function
() { obj.secure =
true
; },
expires:
function
(v) { obj.expires =
new
Date(v); },
'max-age'
:
function
(v) {
if
(obj.expires)
return
; obj.expires =
new
Date((
new
Date()).valueOf() + (v * 1000)); },
path:
function
(v) { obj.path = v; },
domain:
function
(v) { obj.domain = v; }
};
for
(
var
i
in
s) {
I = s[i][0].toLowerCase();
if
(
typeof
f[I] !=
'undefined'
) f[I](s[i].length == 2 ? s[i][1] :
''
);
}
if
(!obj.expires) obj.expires = 0;
obj.name = n.shift();
n = n.map((s) => {
var
f;
try
{
f = decodeURIComponent(s)
}
catch
(e) { f = s }
return
s
})
obj.value = n.join(
'='
);
return
obj;
}