Получить куки по имени


362

У меня есть получатель, чтобы получить значение из куки.

Теперь у меня есть 2 куки по имени shares=и по имени obligations=.

Я хочу сделать этот геттер только для того, чтобы получить значения из файла cookie обязательств.

Как мне это сделать? Таким образом, forданные разбиваются на отдельные значения и помещаются в массив.

 function getCookie1() {
    // What do I have to add here to look only in the "obligations=" cookie? 
    // Because now it searches all the cookies.

    var elements = document.cookie.split('=');
    var obligations= elements[1].split('%');
    for (var i = 0; i < obligations.length - 1; i++) {
        var tmp = obligations[i].split('$');
        addProduct1(tmp[0], tmp[1], tmp[2], tmp[3]);
    }
 }

есть ли смола, которую вы не просто составляете в виде массива?
webLacky3rdClass

делая печенье массив, я должен сказать.
webLacky3rdClass

Нет, как я мог это сделать?


Возможно, вы захотите принять ответ: ваш вопрос все еще помечен как неотвеченный.
Солей - Матье Прево

Ответы:


499

Один подход, который избегает итерации по массиву, был бы:

function getCookie(name) {
  const value = `; ${document.cookie}`;
  const parts = value.split(`; ${name}=`);
  if (parts.length === 2) return parts.pop().split(';').shift();
}

Прохождение

Разделение строки по токену приведет либо к массиву с одной строкой (с одинаковым значением), если токен отсутствует в строке, либо к массиву с двумя строками, если токен найден в строке.

Первый (левый) элемент - это строка того, что было до токена, а второй (справа) - это строка того, что было после токена.

(ПРИМЕЧАНИЕ: если строка начинается с токена, первый элемент является пустой строкой)

Учитывая, что куки хранятся следующим образом:

"{name}={value}; {name}={value}; ..."

чтобы получить определенное значение cookie, нам просто нужно получить строку после "; {name} =" и до следующего ";". Прежде чем приступить к какой-либо обработке, мы добавляем строку cookie с «;», чтобы каждое имя файла cookie, включая первое, было заключено в «;» и «=»:

"; {name}={value}; {name}={value}; ..."

Теперь мы можем сначала разделить на «; {name} =», и если токен найден в строке cookie (т. Е. У нас есть два элемента), мы получим второй элемент, представляющий собой строку, начинающуюся с нашего значения cookie. Затем мы извлекаем это из массива (то есть pop) и повторяем тот же процесс, но теперь с «;» в качестве токена, но на этот раз вытащив левую строку (т. е. сдвиг), чтобы получить фактическое значение токена.


13
@ user3132564 попытался отредактировать это, но на самом деле это комментарий: этот метод возвращает неправильное значение при поиске суффикса cookie - если значение document.cookie равно «FirstName = John» и вы вызываете getCookie («Name "), вы получите" Джон ", даже если с таким именем нет файла cookie. Это также не работает, если имя одного файла cookie является суффиксом другого - если document.cookie имеет значение «Name = John; LastName = Doe», то при вызове split («Name =») возвращается массив с тремя строками, а метод не выполняет t вернуть правильное значение для getCookie («Имя»).
Деннис Джаэруддин

20
Предупреждение о реализации в этом ответе: если существует более одного cookie с одним и тем же именем, то значение cookie не возвращается. Например, если файл cookie с именем stackToken установлен для доменов .stackexchange.com, а также programmers.stackexchange.com, то при вызове getCookie ("stackToken") не будет возвращено ни одно значение - parts.length будет больше 2. Если вы знаете, что все значения
файлов

7
@DennisJaheruddin - похоже, проблема с суффиксами была исправлена.
Натан ДжейБи

2
@ NathanJ.Brauer ты прав. Обновлен для решения этой проблемы давно, но сделал заметку только в журнале изменений, а не в комментариях.
Кирлих

в этом есть вина. Если cookie «имя» и подчеркнуто в другом подобном имени, IE 10+также выдает ошибку. Например: "user": "Joe", "user_name":"Doe"
BOZ

176

Я бы предпочел использовать одно совпадение с регулярным выражением в куки:

window.getCookie = function(name) {
  var match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
  if (match) return match[2];
}

ИЛИ Также мы можем использовать в качестве функции, проверьте код ниже.

function check_cookie_name(name) 
    {
      var match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
      if (match) {
        console.log(match[2]);
      }
      else{
           console.log('--something went wrong---');
      }
   }

Улучшено благодаря Скотту Юнгвирту в комментариях.


11
Это может иметь ложные совпадения, если два куки имеют одинаковый суффикс. Это будет соответствовать как xyz=valueи abcxyz=valueкогда name = xyz.
Брент Уошборн

3
unescape((document.cookie.match(key + '=([^;].+?)(;|$)') || [])[1] || '');Модифицированная версия Glize / DOM / Cookies
Валентин Подкаменный

19
обновите Regex, чтобы new RegExp('(^| )' + name + '=([^;]+)')избежать проблемы, возникшей у @BrentWashburne. Кроме того, я сделал тест jsperf для этого и получил ответ с наибольшим количеством голосов, этот немного выше, но он определенно меньше кода и его легче отслеживать: jsperf.com/simple-get-cookie-by-name
Скотт

5
@ScottJungwirth Да, но затем вы должны обновить инструкцию return, чтобы вернуть соответствие [2];
Джо

@ ScottJungwirth Почему бы и нет new RegExp('(^|;)' + name + '=([^;]+)')? За nameначалом строки или точки с запятой, почему пробел ``?
Junlin

89

используйте скрипт получения куки:

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;
}

тогда назовите это:

var value = readCookie('obligations');

Я украл код выше со страницы куки quirksmode. Вы должны прочитать это .


7
... который украл код из W3schools. Ух ты. w3schools.com/js/js_cookies.asp
WillWam

Эй, по крайней мере, я дал кредит: p также откуда вы знаете, что один был оригиналом?
Мкоряк

Вообще можно предположить, что W3S поставил его на первое место. Они являются домом для многих новичков, которые пишут ctrl-c.
WillWam

На самом деле, похоже, все наоборот :) Quirksmode является / был отличным сайтом для браузерных причуд, и там тоже есть источник. scottandrew.com
sunn0

я люблю w3schools. Пожалуй, лучшая платформа для пожилых людей
Ральф Дингус

56

Если вы используете jQuery, я рекомендую вам использовать этот плагин:

https://github.com/carhartl/jquery-cookie
https://github.com/carhartl/jquery-cookie/blob/master/jquery.cookie.js

<script type="text/javascript"
 src="//cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js">

Таким образом, вы можете прочитать cookie следующим образом:

var value = $.cookie("obligations");

Также вы можете написать cookie:

$.cookie('obligations', 'new_value');
$.cookie('obligations', 'new_value', { expires: 14, path: '/' });

Удалить куки:

$.removeCookie('obligations');

1
Не уверен, почему это не было признано лучшим ответом на самом деле. Да, это jQuery, а не javascript, но в то же время ЭТО !!!!
Cozzbie

21
@Cozzbie, вероятно, включает в себя внешнюю библиотеку (тем самым добавляя еще один http-запрос), чтобы просто получить значение cookie, что является излишним излишним.
rahulserver

Я получаю сообщение об ошибке «Uncaught ReferenceError: $ не определено» в «$ .cookie». Хотя я включил все необходимые библиотеки, такие как jquery.min.js и библиотеку, предложенную в этом ответе.
Адарш Сингх

44

Методы в некоторых других ответах, которые используют регулярное выражение, не охватывают все случаи, в частности:

  1. Когда файл cookie является последним файлом cookie. В этом случае не будет точки с запятой после значения cookie.
  2. Когда имя другого файла cookie заканчивается именем, которое ищется. Например, вы ищете файл cookie с именем «one», и есть файл cookie с именем «done».
  3. Когда имя файла cookie содержит символы, которые не интерпретируются как сами по себе при использовании в регулярном выражении, если им не предшествует обратная косая черта.

Следующий метод обрабатывает эти случаи:

function getCookie(name) {
    function escape(s) { return s.replace(/([.*+?\^${}()|\[\]\/\\])/g, '\\$1'); };
    var match = document.cookie.match(RegExp('(?:^|;\\s*)' + escape(name) + '=([^;]*)'));
    return match ? match[1] : null;
}

Это вернется, nullесли cookie не найден. Он вернет пустую строку, если значение cookie пустое.

Ноты:

  1. Эта функция предполагает, что имена файлов cookie чувствительны к регистру .
  2. document.cookie- Когда это появляется в правой части назначения, оно представляет строку, содержащую список файлов cookie, разделенных точкой с запятой, которые, в свою очередь, являются name=valueпарами. Кажется, что после каждой точки с запятой есть один пробел.
  3. String.prototype.match()- Возвращает, nullкогда совпадений не найдено. Возвращает массив, когда найдено совпадение, а элемент в index [1]является значением первой совпадающей группы.

Примечания регулярного выражения:

  1. (?:xxxx) - формирует несоответствующую группу.
  2. ^ - соответствует началу строки.
  3. | - отделяет альтернативные шаблоны для группы.
  4. ;\\s* - соответствует одной точке с запятой, за которой следует ноль или более пробельных символов.
  5. = - соответствует одному знаку равенства.
  6. (xxxx) - формирует соответствующую группу.
  7. [^;]*- соответствует нулю или более символов, кроме точки с запятой. Это означает, что он будет соответствовать символам до, но не включая точку с запятой или до конца строки.

4
Этот ответ - лучшая и самая короткая функция, которая работает во всех случаях без ложных совпадений. У этого также есть лучшее объяснение того, как это работает. Однако функция escape не объяснена, и я думаю, что если бы автор создал cookie, он бы знал, нужно ли экранировать имя или нет. Так что я бы предпочел более короткую функцию:function getCookie(name) { var match = document.cookie.match(RegExp('(?:^|;\\s*)' + name + '=([^;]*)')); return match ? match[1] : null; }
Джефф Бейкер

Если это универсальный инструмент, он должен либо экранировать имя, либо выдать ошибку, если имя не может быть встроено непосредственно в регулярное выражение. Люди, которые знают ограничения своего приложения, могут удалить побег или охрану.
Джо Лапп

31

Спустя 4 года ES6 значительно упростила версию.

function getCookie(name) {
  let cookie = {};
  document.cookie.split(';').forEach(function(el) {
    let [k,v] = el.split('=');
    cookie[k.trim()] = v;
  })
  return cookie[name];
}

Я также создал суть, чтобы использовать его как Cookieобъект. например, Cookie.set(name,value)иCookie.get(name)

Это читает все куки вместо сканирования. Это нормально для небольшого количества печенья.


23

Я изменил функцию, представленную здесь Джонатаном, используя регулярное выражение, вы можете получить значение cookie по его имени, например так:

function getCookie(name){
    var pattern = RegExp(name + "=.[^;]*")
    var matched = document.cookie.match(pattern)
    if(matched){
        var cookie = matched[0].split('=')
        return cookie[1]
    }
    return false
}

Если он возвращает пустую строку, это означает, что cookie существует, но не имеет значения, если он возвращает false, то cookie не существует. Надеюсь, это поможет.


Просто любопытно, почему вы не использовали varв строке 3? matched = ...
Викторио Берра

Извините, забыл написать.
Мохяддин Алаоддин

14

Вот один из способов получить cookie с определенным именем без необходимости использования каких-либо внешних библиотек:

var cookie = ("; "+document.cookie).split("; YOUR_COOKIE_NAME=").pop().split(";").shift();

Этот ответ основан на блестящем решении Кирлиха . Единственный компромисс этого решения заключается в том, что вы получите пустую строку, когда cookie не существует. Однако в большинстве случаев это не должно нарушать договоренности.


10

Я знаю, что это старый вопрос, но я тоже сталкивался с этой проблемой. Просто для записи, есть небольшой API в веб-странице разработчиков Mozilla .

Yoy может получить любой файл cookie по имени, используя только JS. Код также чище ИМХО (за исключением длинной строки, которую, я уверен, вы можете легко исправить).

function getCookie(sKey) {
    if (!sKey) { return null; }
    return decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null;
}

Как указано в комментариях, имейте в виду, что этот метод предполагает, что ключ и значение были закодированы с использованием encodeURIComponent (). Удалите decode & encodeURIComponent (), если ключ и значение файла cookie не были закодированы.


1
Просто имейте в виду, что метод предполагает, что имя и значение файла cookie были закодированы с использованием времени, encodeURIComponent()когда файл cookie был установлен, что будет истинно, если вы используете функцию-компаньон для установки файла cookie, но это может не всегда иметь место. тест
Джон С

@JohnS Мы могли бы просто удалить decodeURIComponent, верно? (Если бы мы не использовали его для установки куки?) Будет ли он работать?
NiCk Ньюман

Да, только что удалили decodeURI, и это регулярное выражение является монстром. Спасибо Марк, проголосовал!
NiCk Newman

10

Вы можете использовать библиотеку js-cookie для получения и установки файлов cookie JavaScript.

Включить в ваш HTML:

<script src="https://cdn.jsdelivr.net/npm/js-cookie@2/src/js.cookie.min.js"></script>

Чтобы создать Cookie:

Cookies.set('name', 'value');

Чтобы прочитать Cookie:

Cookies.get('name'); // => 'value'

8

Вот довольно короткая версия

 function getCookie(n) {
    let a = `; ${document.cookie}`.match(`;\\s*${n}=([^;]+)`);
    return a ? a[1] : '';
}

Обратите внимание, что я использовал строки шаблона ES6 для составления выражения регулярного выражения.


2
Лучший ответ с сегодняшнего дня. Использует функции ES6. Это 2017 год, и люди все еще используют var, +чтобы объединить и т. Д. -.- '
Элиас Соареш

@EliasSoares В чем проблема использования var?
mrReiha


Не проблема, но использование let - хорошая практика, поскольку во многих ситуациях у нее есть преимущества и почти нет недостатков
Элиас Соареш

7

использование object.defineProperty

С этим вы можете легко получить доступ к куки

Object.defineProperty(window, "Cookies", {
    get: function() {
        return document.cookie.split(';').reduce(function(cookies, cookie) {
            cookies[cookie.split("=")[0]] = unescape(cookie.split("=")[1]);
            return cookies
        }, {});
    }
});

Отныне вы можете просто сделать:

alert( Cookies.obligations );

Это также автоматически обновится, поэтому, если вы измените куки, то Cookiesтоже изменится.


2
Отлично! за исключением того, что это не будет работать для объектов, которые имеют некоторые символы, такие как тире (как имена файлов cookie), и при разбиении объекты сначала имеют пустое пространство, поэтому я иду cookies[(cookie.split("=")[0]).replace(/ /g,'')] = ... Спасибо!!
Самуэль Эль

@ Сэмюэль Эльх правильно, но вы также можете использовать .trim () вместо замены (/ / g, '')
mtizziani

7

Кирлих дал хорошее решение. Тем не менее, это не удается, когда есть два значения cookie с похожими именами, вот простое исправление для этой ситуации:

function getCookie(name) {
  var value = "; " + document.cookie;
  var parts = value.split("; " + name + "=");
  if (parts.length >= 2) return parts.pop().split(";").shift();
}

6

всегда хорошо работает

function getCookie(cname) {
    var name = cname + "=",
        ca = document.cookie.split(';'),
        i,
        c,
        ca_length = ca.length;
    for (i = 0; i < ca_length; i += 1) {
        c = ca[i];
        while (c.charAt(0) === ' ') {
            c = c.substring(1);
        }
        if (c.indexOf(name) !== -1) {
            return c.substring(name.length, c.length);
        }
    }
    return "";
}

function setCookie(variable, value, expires_seconds) {
    var d = new Date();
    d = new Date(d.getTime() + 1000 * expires_seconds);
    document.cookie = variable + '=' + value + '; expires=' + d.toGMTString() + ';';
}

Нет требований для jQuery или чего-либо еще. Чистый старый добрый JavaScript.


6
function getCookie(name) {
    var pair = document.cookie.split('; ').find(x => x.startsWith(name+'='));
    if (pair)
       return pair.split('=')[1]
}

6

Простая функция для получения куки с именем куки:

function getCookie(cn) {
    var name = cn+"=";
    var allCookie = decodeURIComponent(document.cookie).split(';');
    var cval = [];
    for(var i=0; i < allCookie.length; i++) {
        if (allCookie[i].trim().indexOf(name) == 0) {
            cval = allCookie[i].trim().split("=");
        }   
    }
    return (cval.length > 0) ? cval[1] : "";
}

6

По-видимому, MDN никогда не слышал о классе символов регулярных выражений \b, который соответствует смежному \w+, ограниченному с обеих сторон \W+:

getCookie = function(name) {
    var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");
    return r ? r[1] : null;
};

var obligations = getCookie('obligations');

5

Мне кажется, вы могли бы разделить пары ключ-значение cookie на массив и основывать свой поиск на этом:

var obligations = getCookieData("obligations");

Который запускает следующее:

function getCookieData( name ) {
    var pairs = document.cookie.split("; "),
        count = pairs.length, parts; 
    while ( count-- ) {
        parts = pairs[count].split("=");
        if ( parts[0] === name )
            return parts[1];
    }
    return false;
}

Скрипка: http://jsfiddle.net/qFmPc/

Или, возможно, даже следующее:

function getCookieData( name ) {
    var patrn = new RegExp( "^" + name + "=(.*?);" ),
        patr2 = new RegExp( " " + name + "=(.*?);" );
    if ( match = (document.cookie.match(patrn) || document.cookie.match(patr2)) )
        return match[1];
    return false;
}

1
Есть ли способ использовать document.cookie.indexOf (name) и сравнить?

@AndrejHefner Вы можете, хотя это будет соответствовать подстрок. Так что, если у вас есть cookie-файл с именем «foobar» и один с именем «bar», вы можете перепутать «bar» в «foobar» с ключом «bar».
Сэмпсон

@AndrejHefner Пожалуйста, посмотрите более поздний метод, который должен быть быстрее, так как он проверяет соответствие строки.
Сэмпсон

1
Второй метод имеет ошибку, из-за которой он не может найти последнее значение cookie, поскольку он всегда ищет a; в конце. Версия исправления будет:function getCookieData( name ) { var patrn = new RegExp( "(?:^| )" + name + "=(.*?)(?:;|$)" ); if ( match = (document.cookie.match(patrn) )) return match[1]; return false; }
Оз Соломон

5

В своих проектах я использую следующую функцию для доступа к куки по имени

function getCookie(cookie) {
    return document.cookie.split(';').reduce(function(prev, c) {
        var arr = c.split('=');
        return (arr[0].trim() === cookie) ? arr[1] : prev;
    }, undefined);
}

4

Если вам просто нужно проверить, существуют ли какие-либо куки, просто сделайте это:

document.cookie.split('logged=true').length == 2

если cookie logged = true существует, вы получите 2, если не 1.

logged = true - измените это на cookie имя = значение или просто имя


1
Разве это не было бы более читабельным для использования .indexOf() >= 0вместо
Вик Седублюев

3

Здесь уже есть хорошие ответы для получения куки, однако вот мое собственное решение:

function getcookie(cookiename){
var cookiestring  = document.cookie;
var cookiearray = cookiestring.split(';');
for(var i =0 ; i < cookiearray.length ; ++i){ 
    if(cookiearray[i].trim().match('^'+cookiename+'=')){ 
        return cookiearray[i].replace(`${cookiename}=`,'').trim();
    }
} return null;
}

использование: `

     getcookie('session_id');
   // gets cookie with name session_id

3

устанавливается javascript

document.cookie = 'cookiename=tesing';

получить с помощью jquery с плагином jquery-cookie

var value = $.cookie("cookiename");

alert(value);

@cytsunny - это потому, что для этого вам нужен плагин jquery cookie.
Алекс Стэндифорд

Ух ты ... какая важная информация ранее отсутствовала .... Но по предоставленной вами ссылке кажется, что владелец библиотеки решил, что ему лучше удалить зависимость jquery.
cytsunny


2

Мое решение таково:

function getCookieValue(cookieName) {
    var ca = document.cookie.split('; ');
    return _.find(ca, function (cookie) {
        return cookie.indexOf(cookieName) === 0;
    });
}

Эта функция использует функцию Underscorejs _.find. Возвращает неопределенное значение, если имя файла cookie не существует


2

Я сделал это таким образом. так что я получаю объект для доступа к отдельным значениям. С этим вы можете передать cookie родительскому элементу, а затем вы можете получить доступ к своим значениям с помощью ключей, таких как

var cookies=getCookieVal(mycookie);
alert(cookies.mykey);
function getCookieVal(parent) {
            var cookievalue = $.cookie(parent).split('&');
            var obj = {};
            $.each(cookievalue, function (i, v) {
                var key = v.substr(0, v.indexOf("="));
                var val = v.substr(v.indexOf("=") + 1, v.length);

                obj[key] = val;

            });
            return obj;
        }  

1

Функциональный подход к поиску существующих куки. Он возвращает массив, поэтому он поддерживает несколько вхождений с одним и тем же именем. Он не поддерживает частичное совпадение ключей, но тривиально заменить === в фильтре на регулярное выражение.

function getCookie(needle) {
    return document.cookie.split(';').map(function(cookiestring) {
        cs = cookiestring.trim().split('=');

        if(cs.length === 2) {
            return {'name' : cs[0], 'value' : cs[1]};
        } else {
            return {'name' : '', 'value' : ''};
        }
    })
    .filter(function(cookieObject) { 
        return (cookieObject.name === needle);
    });
}

1

Просто используйте следующую функцию (чистый код JavaScript)

const getCookie = (name) => {
 const cookies = Object.assign({}, ...document.cookie.split('; ').map(cookie => {
    const name = cookie.split('=')[0];
    const value = cookie.split('=')[1];

    return {[name]: value};
  }));

  return cookies[name];
};

1

Получить куки по имени, просто передайте имя куки в функцию ниже

function getCookie(cname) {
  var name = cname + "=";
  var decodedCookie = decodeURIComponent(document.cookie);
  var ca = decodedCookie.split(';');
  for(var i = 0; i <ca.length; i++) {
    var c = ca[i];
    while (c.charAt(0) == ' ') {
      c = c.substring(1);
    }
    if (c.indexOf(name) == 0) {
      return c.substring(name.length, c.length);
    }
  }
  return "";
}

0

Следующая функция вернет key-valueпару необходимых файлов cookie, где keyбудет указано имя файла cookie и valueзначение файла cookie.

/**
 * Returns cookie key-value pair
 */
var getCookieByName = function(name) {
    var result = ['-1','-1'];
    if(name) {
        var cookieList = document.cookie.split(';');
        result = $.grep(cookieList,function(cookie) { 
            cookie = cookie.split('=')[0];
            return cookie == name;
        });
    }
    return result;
};

0

Пример файлов cookie: пример JS:

document.cookies = {
   create : function(key, value, time){
     if (time) {
         var date = new Date();
         date.setTime(date.getTime()+(time*24*60*60*1000));
         var expires = "; expires="+date.toGMTString();
     }
     else var expires = "";
     document.cookie = key+"="+value+expires+"; path=/";
   },
   erase : function(key){
     this.create(key,"",-1);
   },
   read : function(key){
     var keyX = key + "=";
     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(keyX) == 0) return   c.substring(keyX.length,c.length);
     }
     return null;
   }
}

Храните массивы и объекты с помощью json или xml

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.