【问题标题】:document.cookie.match inconsistent, sometimes extracting wrong cookie valuedocument.cookie.match 不一致,有时会提取错误的 cookie 值
【发布时间】:2015-05-07 13:31:52
【问题描述】:

我有以下脚本(在 Google 跟踪代码管理器中使用)

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 技能非常糟糕,无法弄清楚如何解决这个问题。关于我必须解决的问题有什么想法吗?

【问题讨论】:

  • 这不是一个真正的谷歌分析问题。没有代码试图将结果传递给 google-analytics,所以我回答了有关修复 cookie 匹配代码的问题。如果您在 google 分析部分仍然需要帮助,请提出一个针对 google 分析部分的新问题。

标签: javascript regex cookies google-tag-manager


【解决方案1】:

对我必须解决的问题有什么想法吗?

您需要修复用于匹配的regular expression。 document.cookie.match() 中括号中的参数是一个正则表达式。

来自MDN, document.cookie 是所有cookie 的字符串,由; 分隔。因为document.cookie 只是一个String document.cookie.match() 只是调用String.match()String.match(regexp) 使用正则表达式参数 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,实际上它尽可能匹配,并允许正则表达式匹配所需 cookie 的开头、字符串中的所有其他 cookie 以及其他一些 cookie 中的数字。由于 document.cookie 中的各个 cookie 可能无法保证按任何特定顺序排列,因此贪婪匹配的行为可能不一致。当所需的 cookie 位于字符串的末尾时,您将得到正确的结果。在其他时候,您不会,当.+ 匹配太多并且末尾的某个其他 cookie 有 6 个数字可以匹配时。

备选方案#1:编写一个简短的函数来拆分; 上的cookie 字符串,它将拆分为一个字符串数组,然后将每个字符串分别输入匹配项并返回第一个匹配项。这可以防止正则表达式在完整的 cookie 字符串中进行错误匹配。

备选方案 #2:修复正则表达式以仅匹配您想要的内容。您可以使用http://refiddle.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'

【讨论】:

    猜你喜欢
    • 2012-10-10
    • 1970-01-01
    • 1970-01-01
    • 2016-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-03
    • 1970-01-01
    相关资源
    最近更新 更多