Предположения
Исходя из вопроса, я считаю, что некоторые предположения / требования для этой функции включают в себя:
- Он будет использоваться в качестве библиотечной функции и, следовательно, предназначен для добавления в любую кодовую базу;
- Как таковой, он должен работать во многих различных средах , то есть работать с устаревшим кодом JS, CMS различных уровней качества и т. Д .;
- Чтобы взаимодействовать с кодом, написанным другими людьми, и / или кодом, который вы не контролируете, функция не должна делать какие-либо предположения о том, как кодируются имена или значения файлов cookie . Вызов функции со строкой
"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 (на основе петель):
function readCookie(name) {
name += '=';
for (var ca = document.cookie.split(/;\s*/), i = ca.length - 1; i >= 0; i--)
if (!ca[i].indexOf(name))
return ca[i].replace(name, '');
}
который при минимизации составляет 128 символов (не считая имени функции):
function readCookie(n){n+='=';for(var a=document.cookie.split(/;\s*/),i=a.length-1;i>=0;i--)if(!a[i].indexOf(n))return a[i].replace(n,'');}
Функция на основе регулярных выражений
Обновление: если вы действительно хотите решение с регулярными выражениями:
function readCookie(name) {
return (name = new RegExp('(?:^|;\\s*)' + ('' + name).replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') + '=([^;]*)').exec(document.cookie)) && name[1];
}
Это экранирует любые специальные символы в имени файла cookie перед созданием объекта RegExp. Сокращено до 134 символов (не считая названия функции):
function readCookie(n){return(n=new RegExp('(?:^|;\\s*)'+(''+n).replace(/[-[\]{}()*+?.,\\^$|#\s]/g,'\\$&')+'=([^;]*)').exec(document.cookie))&&n[1];}
Как указали в комментариях Rudu и cwolves, регулярное выражение, экранирующее регулярное выражение, может быть сокращено на несколько символов. Я думаю, что было бы хорошо, чтобы регулярное выражение оставалось последовательным (вы можете использовать его в другом месте), но их предложения стоит рассмотреть.
Ноты
Обе эти функции не будут обрабатываться null
или undefined
, то есть, если есть файл cookie с именем «null», readCookie(null)
вернут его значение. Если вам нужно разобраться с этим делом, адаптируйте код соответствующим образом.