Предположения
Исходя из вопроса, я полагаю, что некоторые предположения / требования для этой функции включают:
- Он будет использоваться как библиотечная функция и, следовательно, предназначен для удаления в любую кодовую базу;
- Как таковой, он должен будет работать во многих различных средах , т. Е. Работать с унаследованным кодом JS, CMS различных уровней качества и т. Д .;
- Для взаимодействия с кодом, написанным другими людьми, и / или кодом, который вы не контролируете, функция не должна делать никаких предположений о том, как кодируются имена или значения файлов cookie . Вызов функции со строкой
"foo:bar[0]"
должен вернуть cookie (буквально) с именем "foo: bar [0]";
- Новые файлы cookie могут быть записаны и / или существующие файлы cookie, измененные в любой момент времени существования страницы.
При этих предположениях ясно, что encodeURIComponent
/ decodeURIComponent
не следует использовать ; при этом предполагается, что код, который устанавливает cookie, также закодировал его с помощью этих функций.
Подход с использованием регулярных выражений становится проблематичным, если имя файла cookie может содержать специальные символы. jQuery.cookie решает эту проблему, кодируя имя файла cookie (фактически имя и значение) при сохранении файла cookie и расшифровывая имя при получении файла cookie. Ниже приведено решение для регулярных выражений.
Если только вы не читаете куки, которые полностью контролируете, было бы также целесообразно читать куки из document.cookie
напрямую и не кэшировать результаты, так как нет способа узнать, является ли кеш недопустимо без чтения document.cookie
снова.
(Хотя доступ и синтаксический анализ document.cookies
будут немного медленнее, чем при использовании кэша, он не будет таким же медленным, как чтение других частей DOM, поскольку файлы cookie не играют роли в DOM / деревьях рендеринга.)
Петлевая функция
Вот ответ 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)
вернет его значение. Если вам нужно разобраться с этим делом, измените код соответствующим образом.