Какой самый короткий, точный и совместимый с браузером метод чтения файлов cookie в JavaScript?
Очень часто, при создании автономных скриптов (где у меня не может быть никаких внешних зависимостей), я добавляю функцию для чтения куки и обычно прибегаю кreadCookie()
методу QuirksMode.org (280 байт, 216 минимизировано).
function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
}
Это делает работу, но это уродливо, и каждый раз добавляет немного вздутия.
Метод, в котором jQuery.cookie использует что-то вроде этого (модифицированный, 165 байт, 125 минимизированный):
function read_cookie(key)
{
var result;
return (result = new RegExp('(?:^|; )' + encodeURIComponent(key) + '=([^;]*)').exec(document.cookie)) ? (result[1]) : null;
}
Обратите внимание, что это не соревнование «Code Golf»: я законно заинтересован в уменьшении размера моей функции readCookie и в том, чтобы решение, которое у меня есть, было действительным.
javascript
cookies
Yahel
источник
источник
Ответы:
Короче, надежнее и эффективнее, чем текущий, получивший наибольшее количество голосов:
Сравнение производительности различных подходов показано здесь:
http://jsperf.com/get-cookie-value-regex-vs-array-functions
Некоторые замечания о подходе:
Подход regex не только самый быстрый в большинстве браузеров, но и дает самую короткую функцию. Кроме того, следует указать, что в соответствии с официальной спецификацией (RFC 2109) пробел после точки с запятой, разделяющей файлы cookie в document.cookie, является необязательным, и можно привести аргумент, что на него не следует полагаться. Кроме того, пробел допускается до и после знака равенства (=), и может быть выдвинут аргумент, что этот потенциальный пробел должен быть включен в любой надежный анализатор document.cookie. Приведенное выше регулярное выражение учитывает оба указанных выше условия пробела.
источник
getCookieValue(a, b)
принимает параметрb
?a
и какb
делать.a
Параметр не является регулярным выражением, хотя это может быть полезно, это не безопасно. Такие вещиgetCookieValue('.*')
вернут любое случайное печеньеЭто только когда-либо попадет в document.cookie ОДИН раз. Каждый последующий запрос будет мгновенным.
Боюсь, что на самом деле нет более быстрого способа, чем эта общая логика, если только вы не можете свободно использовать,
.forEach
который зависит от браузера (даже если вы не экономите так много)Ваш собственный пример слегка сжат
120 bytes
:Вы можете получить это
110 bytes
если сделаете его однобуквенным именем функции,90 bytes
если отпуститеencodeURIComponent
.Я понял это
73 bytes
, но, если честно, это82 bytes
когда названоreadCookie
и102 bytes
когда добавленоencodeURIComponent
:источник
()
вызова в конце, поэтому он определял анонимную функцию, но никогда не выполнял ее.Предположения
Исходя из вопроса, я считаю, что некоторые предположения / требования для этой функции включают в себя:
"foo:bar[0]"
должен вернуть cookie (буквально) с именем "foo: bar [0]";При этих предположениях ясно, что
encodeURIComponent
/decodeURIComponent
не следует использовать ; при этом предполагается, что код, который устанавливает cookie, также закодировал его, используя эти функции.Подход с использованием регулярных выражений становится проблематичным, если имя файла cookie может содержать специальные символы. jQuery.cookie решает эту проблему, кодируя имя файла cookie (фактически имя и значение) при сохранении файла cookie и расшифровывая имя при получении файла cookie.Регулярное выражение решение ниже.Если вы только не читаете файлы cookie, которые полностью контролируете, было бы также целесообразно считывать файлы cookie
document.cookie
напрямую, а не кэшировать результаты, поскольку невозможно узнать, является ли кэш недействительным без чтения.document.cookie
повторного .(Хотя доступ и анализ
document.cookies
будут немного медленнее, чем при использовании кэша, он не будет таким же медленным, как чтение других частей DOM, поскольку файлы cookie не играют роли в деревьях DOM / render.)Петлевая функция
Вот ответ Code Golf, основанный на функции PPK (на основе петель):
который при минимизации составляет 128 символов (не считая имени функции):
Функция на основе регулярных выражений
Обновление: если вы действительно хотите решение с регулярными выражениями:
Это экранирует любые специальные символы в имени файла cookie перед созданием объекта RegExp. Сокращено до 134 символов (не считая названия функции):
Как указали в комментариях Rudu и cwolves, регулярное выражение, экранирующее регулярное выражение, может быть сокращено на несколько символов. Я думаю, что было бы хорошо, чтобы регулярное выражение оставалось последовательным (вы можете использовать его в другом месте), но их предложения стоит рассмотреть.
Ноты
Обе эти функции не будут обрабатываться
null
илиundefined
, то есть, если есть файл cookie с именем «null»,readCookie(null)
вернут его значение. Если вам нужно разобраться с этим делом, адаптируйте код соответствующим образом.источник
#\s
в конце вашего замены-Regex? Эту общую замену можно немного упростить (-, не имеют смысла, кроме экранированных скобок):/[[\]{}()*+?.\\^$|]/g
она может быть дажеencodeURIComponent
/[()*.\\]/g
new RegExp('[' + str + ']')
то вы хотели бы убежать-
), так что вы, вероятно, правы, что его можно сократить. Так как это сохранит только несколько байтов, а экранирование лишних символов не повлияет на окончательное регулярное выражение, я склонен оставить все как есть.encodeURIComponent()
в этом случае, потому что я думаю, что OP ищет универсальную функцию, которая может работать с любым именем cookie. Если сторонний код устанавливает cookie с именем «foo: bar», использованиеencodeURIComponent()
будет означать попытку чтения cookie с именем «foo% 3Abar».a<tab>b
вa\<tab>b
... что недопустимо, хотя и\<space>
есть). И, кажется, # не имеет никакого значения в JSencodeURIComponent
, если файл cookie был назван,foo=
он будет сохранен, так какfoo%3D
без кодирования имени вы его не найдете (ваш код его не найдет) - правильного ответа нет. Если вы можете контролировать, как вставляются файлы cookie, вы можете упростить ответ / сделать предположения, чтобы помочь его получить. Самое простое / лучшее - это использовать только a-zA-Z0-9 в качестве имени файла cookie и избегать всегоencodeURIComponent
беспорядка, избегающего RegExp. Но вам все равно придется беспокоиться оdecodeURIComponent
на значении печенья , так как это рекомендованная практика.код из Google Analytics ga.js
источник
return d[0];
а затем я использовал,if (c('EXAMPLE_CK') == null)
чтобы проверить, если cookie не определен.Как насчет этого?
Подсчитано 89 байт без имени функции.
источник
k
можно было бы назватьkey
для ясности, но в любом случае.Здесь идет .. Ура!
Обратите внимание, что я использовал шаблонные строки ES6 для составления выражения регулярного выражения.
источник
это в объекте, который вы можете читать, писать, перезаписывать и удалять куки.
источник
Обе эти функции выглядят одинаково действительными с точки зрения чтения cookie. Вы можете сбрить несколько байтов (и это действительно проникает на территорию Code Golf):
Все, что я сделал с этим, это свел все объявления переменных в один оператор var, удалил ненужные вторые аргументы в вызовах подстроки и заменил один вызов charAt на разыменование массива.
Это все еще не так коротко, как вторая функция, которую вы предоставили, но даже она может удалить несколько байтов:
Я изменил первое подвыражение в регулярном выражении, чтобы оно было подхватывающим, и изменил часть результата [1] на результат [2], чтобы он совпадал с этим изменением; также убрал лишние паренсы вокруг результата [2].
источник
Чтобы действительно удалить как можно больше вздутия, не используйте функцию-обертку вообще:
Пока вы знакомы с RegEx, этот код достаточно чистый и легко читаемый.
источник
(редактировать: сначала опубликована неверная версия ... и не функциональная. Обновлена до текущей, которая использует непарамальную функцию, очень похожую на второй пример.)
Хорошая идея в первом примере cwolves. Я использовал обе функции для довольно компактной функции чтения / записи cookie, которая работает в нескольких поддоменах. Подумал, что поделюсь, если кто-нибудь еще перебирает эту тему в поисках этого.
источник
Используя ответ cwolves, но не используя замыкание или предварительно вычисленный хеш:
... и минимизация ...
... равно 127 байтов.
источник
Вот простейшее решение с использованием строковых функций javascript.
источник
Следующая функция позволит различать пустые строки и неопределенные файлы cookie. Неопределенные куки вернутся правильно,
undefined
а не пустая строка, в отличие от некоторых других ответов здесь. Но это не будет работать в IE7 и ниже, так как они не разрешают доступ массива к строковым индексам.источник