regex document.cookie.match不一致,有时提取错误的cookie值

js81xvg6  于 2023-05-08  发布在  其他
关注(0)|答案(1)|浏览(144)

我有以下脚本(在谷歌标签管理器中使用)

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技能也很差,无法解决这个问题。你知道我该修什么吗?

wsewodh2

wsewodh21#

你知道我该修什么吗?
您需要修复用于匹配的regular expression。document.cookie.match()中括号中的参数是一个正则表达式。
From MDN, document.cookie是所有cookie的字符串,由;分隔。由于document.cookie只是一个Stringdocument.cookie.match()只是调用String.match()String.match(regexp)使用正则表达式参数regexp查找匹配的Array。
你使用的regexp是:

comagic_visitor.+=.+%7C%7C.+(\\d{6})\;

这个正则表达式意味着匹配必须满足以下所有条件:

  1. comagic_visitor以comagic_visitor开始
  2. .+后跟一个或多个其他字符(除换行符和其他几个字符外的任何字符)。* 这很危险 *
  3. =后接=
  4. .+后跟一个或多个其他字符 * 同样,可能很危险 *
  5. %7C有一点危险,这取决于你在哪里使用它,它可能是一个文字%7C,也可能被翻译成|,意思是“或”。
  6. .+一个或多个其他字符
  7. (\\d{6})括号将其提取为匹配结果,\d{6}正好是6位数。它似乎被一个额外的\转义了,如果你使用/regexp/而不是"regexp",这将是不必要的。
  8. \;是转义的;,它需要最后的;
    主要问题:这个正则表达式太松散了,匹配的内容远远超出预期。.+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,必须允许匹配;,如果我们否认这些错误匹配应该是不可能的。
    就像这样:
var cml = document.cookie.match(/comagic_visitor[^;]+(\d{6})\;/)[1];

这在nodejs中很有用。

d = "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";
r = /comagic_visitor[^;]+(\d{6})\;/
d.match(r)[1]
---> '972212'

相关问题