Any ideas on what I have to fix?
You need to fix the regular expression used for matching. The argument in parenthesis in document.cookie.match() is a regular expression.
From MDN, document.cookie
is a string of all the cookies, separated by ;
. Since document.cookie
is simply a String
document.cookie.match()
is simply calling String.match()
. String.match(regexp)
finds an Array of matches using the regular expression parameter regexp
.
The regexp you are using is:
comagic_visitor.+=.+%7C%7C.+(\\d{6})\;
This regexp means a match must satisfy all of the following conditions:
comagic_visitor
begin with comagic_visitor
.+
followed by one or more other characters (any chars except newline and a couple others). This can be dangerous
=
followed by =
.+
followed by one or more other characters Again, can be dangerous
%7C
is a little dangerous depending on where you use it, and might be a literal %7C
or could be translated into |
which means "or"
.+
one or more other characters
(\\d{6})
the parenthesis extract this as the result of the match, and \d{6}
is exactly 6 digits. It seems to be escaped by an extra \
which would be unnecessary if you used /regexp/
instead of "regexp"
\;
is an escaped ;
, which requires the final ;
Primary Issue: This regexp is much too loose and matches much more than desirable. .+
is greedy, in practice it matches as much as it can, and allows the regexp to match the beginning of the desired cookie, all the other cookies in the string, and the digits in some other cookie. Since the individual cookies in document.cookie
are probably not guaranteed to be in any particular order, a greedy match can behave inconsistently. When the desired cookie is at the end of the string, you will get the correct result. At other times, you won't, when the .+
matches too much and there are 6 digits at some other cookie at the end that can be matched.
Alternative #1: Write a short function to split your cookie string on ;
which will split into an array of strings and then feed each string into match separately and return the first match. This prevents the regexp from making a bad match in the full cookie string.
Alternative #2: Fix the regexp to match only what you want. You can use https://regex101.com/ or a console window to test regular expressions. Possibly you can change the .+
to [^;]+
which changes any char except newline
to any char except ;
and that might fix it, because to match across multiple cookies in the full cookie string it has to be allowed to match a ;
and if we deny that those false matches should be impossible.
Like this:
var cml = document.cookie.match(/comagic_visitor[^;]+(\d{6})\;/)[1];
This works for me in 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'