在百度小程序中对set-cookie的处理

在后端API返回的响应头中,包含了12条set-cookie

百度小程序(以及微信小程序)对此的处理是:将多个同名的响应头用半角逗号,JOIN成一长串字符串。原因是因为response.header是一个Object对象。

由于cookie信息中往往会存在Expires过期时间信息,而这种GMT时间格式是有可能存在半角逗号的,会与header的JOIN字符冲突,所以如果简单使用

cookieStr.split(',')
复制代码

来切割cookie,会导致cookie解析不正确。看一下cookie样本:

let badCookie = `
    route=xxx; Path=/,
    authId=xxx;domain=.xxx.com;path=/;HTTPOnly;, 
    secureToken=xxx;domain=.xxx.com;path=/;secure;HTTPOnly;, 
    path=/; domain=.xxx.com; Max-Age=1728000; 
    Expires=Sat, 22-Dec-2018 05:30:39 GMT, 
    
`;
复制代码

采用的处理方式也比较简单粗暴:进行特殊值保护

在切割cookie之前,先对引起冲突的日期做转换,保护日期值不会被split破坏。

export const pluginFixGMTDateTime = cookie =>
    (cookie + '').replace(
        /\=(Mon|Tue|Wed|Thu|Fri|Sat|Sun)\s*\,/g,
        '=$1'
    );
复制代码

除此之外,我们还需要对cookie做头尾去空字符串、整体去换行符等清理工作。

export const pluginTrim = s =>
    (s + '').replace(/^\s+|\s+$/g, '');

export const pluginLinear = s =>
    (s + '').replace(/[\r\n]+/g, '');
复制代码

用插件形式写清理方法,目的是方便以后扩展。

在进行切割之前,我们先把插件组织起来,做一个专门的清理工具:

export const prepareString = (s, ...plugin) => {
    plugin = [
        pluginTrim,
        pluginLinear,
        pluginFixGMTDateTime,
        ...plugin
    ];
    return plugin.length < 1
        ? s
        : plugin.length === 1
            ? plugin[0](s)
            : plugin.reduce((a, b) => 
                typeof(a) === 'function' ? b(a(s)) : b(a)
            );
};
复制代码

在cookie切割之后,我们还需要将每一个key-value结构的键值对取出来,依然用正则:

export const cookieItemRegExp = 
    /([\w\-_]+)(\s*\=\s*((Mon|Tue|Wed|Thu|Fri|Sat|Sun).+?GMT|[^;\,]+))?/g
    ;
复制代码

这里的正则其实也包含特殊值保护,但cookie是一种特殊结构,需要按条解析,所以不能直接用此正则匹配cookie全文。

现在都已经准备好了,我们可以开始动手解析cookie了:

export const cookieParser = (cookie, ...plugin) => {
    let cleanCookie = prepareString(cookie + '', ...plugin);
    let cookieSegments = cleanCookie.split(',').map(s => pluginTrim(s));
    let cookies = [];
    cookieSegments.forEach(cookieStr => {
        if(cookieStr.length < 1) return;
        let ms = cookieStr.match(cookieItemRegExp), cookieObj = {};
        if(ms){
            ms.forEach(m => {
                let idx = m.indexOf('='), key, val;
                if(idx > -1){
                    key = m.substr(0, idx);
                    val = m.substr(idx + 1);
                } else {
                    key = m;
                    val = null;
                }
                cookieObj[key] = val;
            })
        }
        cookies.push({ cookieStr, cookieObj })
    });
    return cookies;
};
复制代码

解析badCookie输出结果

转载于:https://juejin.im/post/5c07dbb55188257f30199925

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值