我有以下脚本(在谷歌标签管理器中使用)
function() {
try {
var cml = document.cookie.match("comagic_visitor.+=.+%7C%7C.+(\\d{6})\;")[1];
if (cml !== undefined) {
return cml;
}
} catch(e) {}
return 'false';
}
它必须获取cookie值。Cookie的名称可能会更改,但其第一部分始终保持不变“_comagic_visitor”。
由于某种原因,当我使用代码在控制台中获取cookie值时,我得到了正确的值:
PHPSESSID=3reongfce35dl150rbdkkllto0; region=2; region2=2; _gat_UA-XXXXXX-2=1; _ym_visorc_263098=w; _ga=GA1.3.26804606X.X431002649; _comagic_visitorTH17k=cASNWQ3N9mRZT8tSmUtTGs5IG9LaD7BPHtCCiEpq_fpSnSKGMcCsEG0kPVur16gH%7C%7C124972212; _comagic_sessionTH17k=203937260
价值:972212
但使用它与标签管理器,我得到937260(正如你所看到的是从“_comagic_session”(最后6位)。
不幸的是,我不擅长调试,我的js技能也很差,无法解决这个问题。你知道我该修什么吗?
1条答案
按热度按时间wsewodh21#
你知道我该修什么吗?
您需要修复用于匹配的regular expression。document.cookie.match()中括号中的参数是一个正则表达式。
From MDN,
document.cookie
是所有cookie的字符串,由;
分隔。由于document.cookie
只是一个String
,document.cookie.match()
只是调用String.match()
。String.match(regexp)
使用正则表达式参数regexp
查找匹配的Array。你使用的regexp是:
这个正则表达式意味着匹配必须满足以下所有条件:
comagic_visitor
以comagic_visitor开始.+
后跟一个或多个其他字符(除换行符和其他几个字符外的任何字符)。* 这很危险 *=
后接=
.+
后跟一个或多个其他字符 * 同样,可能很危险 *%7C
有一点危险,这取决于你在哪里使用它,它可能是一个文字%7C
,也可能被翻译成|
,意思是“或”。.+
一个或多个其他字符(\\d{6})
括号将其提取为匹配结果,\d{6}
正好是6位数。它似乎被一个额外的\
转义了,如果你使用/regexp/
而不是"regexp"
,这将是不必要的。\;
是转义的;
,它需要最后的;
主要问题:这个正则表达式太松散了,匹配的内容远远超出预期。
.+
是greedy,在实践中,它尽可能多地匹配,并允许regexp匹配所需cookie的开头,字符串中的所有其他cookie以及其他cookie中的数字。由于document.cookie
中的单个cookie可能无法保证按任何特定顺序排列,因此贪婪匹配可能会表现得不一致。当所需的cookie位于字符串的末尾时,您将获得正确的结果。在其他时候,你不会,当.+
匹配太多,有6个数字在一些其他cookie在年底可以匹配。备选方案1:写一个简短的函数来分割
;
上的cookie字符串,它将分割成一个字符串数组,然后将每个字符串分别输入match并返回第一个匹配。这可以防止regexp在完整的cookie字符串中进行错误的匹配。备选方案2:修复regexp,使其只匹配您想要的内容。您可以使用https://regex101.com/或控制台窗口来测试正则表达式。也许你可以将
.+
更改为[^;]+
,将any char except newline
更改为any char except ;
,这可能会解决这个问题,因为要在完整的cookie字符串中匹配多个cookie,必须允许匹配;
,如果我们否认这些错误匹配应该是不可能的。就像这样:
这在nodejs中很有用。