如何使用Fetch API读取含过期日期的多个Set-Cookie请求头?
问题背景
使用Fetch API读取合并后的多个Cookie时,直接通过request.headers.get('cookie').split(',')拆分会失效——因为Cookie的Expires属性值里包含逗号(比如Tue, 04 Aug 2020 19:45:53 GMT),这种拆分方式会把日期里的逗号也当成Cookie之间的分隔符,导致拆分结果混乱。
举个例子,给定以下Cookie字符串:
Cookie: cookie1=value1; Path=/; Expires=Tue, 04 Aug 2020 19:45:53 GMT; HttpOnly, cookie2=value2; Path=/; Expires=Tue, 05 Sept 2020 14:32:03 GMT; HttpOnly
用split(',')拆分后,Tue会被当成一个独立的“Cookie片段”,完全不符合预期。
解决方案:精准正则拆分
核心思路是只把逗号后面紧跟Cookie键值对(xxx=)的情况,视为Cookie之间的分隔符,忽略日期里的逗号。可以通过正则表达式的正向预查实现:
基础拆分代码
const cookieHeader = request.headers.get('cookie'); // 匹配 ", " 后接Cookie键(字母数字开头)的位置,作为拆分点 const individualCookies = cookieHeader.split(/,(?=\s*\w+=)/);
正则/(?=\s*\w+=)/是正向预查规则:确保逗号后面是可选的空格,再接着Cookie的键(\w+=),这样就不会把日期里的, 04误判成分隔符。
完整Cookie解析函数
如果需要进一步解析每个Cookie的键、值和属性(比如过期时间、路径),可以用以下函数:
const parseCookieHeader = (cookieHeader) => { if (!cookieHeader) return {}; // 拆分多个独立Cookie const cookieSegments = cookieHeader.split(/,(?=\s*\w+=)/); return cookieSegments.reduce((cookieMap, segment) => { // 拆分键值部分和属性部分 const [keyValue, ...attrs] = segment.split(';').map(item => item.trim()); const [cookieKey, cookieValue] = keyValue.split('=').map(decodeURIComponent); // 解析属性(如Expires、Path、HttpOnly) const attributes = attrs.reduce((attrMap, attr) => { if (attr.includes('=')) { const [attrKey, attrVal] = attr.split('='); attrMap[attrKey.toLowerCase()] = attrVal; } else { // 无值属性(如HttpOnly)设为true attrMap[attr.toLowerCase()] = true; } return attrMap; }, {}); cookieMap[cookieKey] = { value: cookieValue, ...attributes }; return cookieMap; }, {}); }; // 使用示例 const cookies = parseCookieHeader(request.headers.get('cookie')); console.log(cookies.cookie1.value); // 输出: value1 console.log(cookies.cookie1.expires); // 输出: Tue, 04 Aug 2020 19:45:53 GMT
补充说明
如果是在浏览器端发起Fetch请求,浏览器会自动处理Cookie的发送与存储,无需手动读取Cookie请求头;但如果是在Service Worker、Node.js环境(使用node-fetch)中处理请求时,就需要手动解析Cookie header,此时上述方法就能完美解决日期含逗号的问题。
内容的提问来源于stack exchange,提问作者Sharlaan
相关产品推荐
相关产品推荐

