Как проверить, существует ли файл cookie?


84

Какой хороший способ проверить, существует ли cookie?

Условия:

Cookie существует, если

cookie1=;cookie1=345534;
//or
cookie1=345534;cookie1=;
//or
cookie1=345534;

Cookie не существует, если

cookie=;
//or
<blank>

Ответы:


127

Вы можете вызвать функцию getCookie с именем нужного файла cookie, а затем проверить, равно ли оно = null.

function getCookie(name) {
    var dc = document.cookie;
    var prefix = name + "=";
    var begin = dc.indexOf("; " + prefix);
    if (begin == -1) {
        begin = dc.indexOf(prefix);
        if (begin != 0) return null;
    }
    else
    {
        begin += 2;
        var end = document.cookie.indexOf(";", begin);
        if (end == -1) {
        end = dc.length;
        }
    }
    // because unescape has been deprecated, replaced with decodeURI
    //return unescape(dc.substring(begin + prefix.length, end));
    return decodeURI(dc.substring(begin + prefix.length, end));
} 

function doSomething() {
    var myCookie = getCookie("MyCookie");

    if (myCookie == null) {
        // do cookie doesn't exist stuff;
    }
    else {
        // do cookie exists stuff
    }
}

3
Поскольку unescapeне рекомендуется использовать decodeURIComponentвместо этого?
the_nuts

3
@the_nuts, Хороший улов. Я этого не знал. Согласно w3cschools, decodeURI () или decodeURIComponent можно использовать для замены unescape. Выбор того, что использовать, может зависеть от того, что хранится, я выбрал decodeURI, потому что не ожидаю, что в файле cookie будут закодированные символы-разделители. Полная ссылка: w3schools.com/jsref/jsref_decodeuri.asp
jac

3
это не работает с первым файлом cookie, потому что переменная end не установлена
марш

функция doSomething ($ name) {var myCookie = getCookie ($ name);
Соль

1
Это прекрасный пример того, почему w3schools не является надежным источником и почему вы не должны копировать / вставлять ответы из него. Вы бы избегали использования == и! =, Которые довольно хорошо известны в js.
Исаак Пак

96

Я создал альтернативную версию, отличную от jQuery:

document.cookie.match(/^(.*;)?\s*MyCookie\s*=\s*[^;]+(.*)?$/)

Он только проверяет наличие файлов cookie. Более сложная версия также может возвращать значение cookie:

value_or_null = (document.cookie.match(/^(?:.*;)?\s*MyCookie\s*=\s*([^;]+)(?:.*)?$/)||[,null])[1]

Поместите свое имя файла cookie вместо MyCookie.


14
чудесное чистое решение! В наши дни люди слишком быстро берут плагины ... слишком много накладных расходов. Это очень хорошее решение!
Патрик

3
Это не работает. В регулярном выражении отсутствует пробел. Это должен быть document.cookie.match (/^(.*;)? MyCookie = [^;] + (. *)? $ /), Обратите внимание на пробел после?.
Богдан М.

1
document.cookie возвращает файлы cookie, разделенные пробелами, например: cookie1 =; cookie1 = 345534;
Богдан М.

1
@BogdanM. : Нет пробела для первого файла cookie! / [] {0,1} / См. Мой комментарий выше
Габриэль,

6
Если вы хотите использовать переменную: new RegExp ("^ (?:. *;)? \\ s *" + cookieName + "\\ s * = \\ s * ([^;] +) (?:. *) $ ")?
йозеф

34
document.cookie.indexOf('cookie_name=');

Он вернется, -1если этот файл cookie не существует.

ps Единственный недостаток (как упоминалось в комментариях) в том, что он ошибается, если установлен файл cookie с таким именем: any_prefix_cookie_name

( Источник )


5
Это также соответствует любым файлам cookie со строкой в ​​их имени. Например, пример возвращает что-то иное, чем -1если cookie_name_whateverустановлено (даже если cookie_name не установлено). Версия регулярного выражения в другом ответе решает это.
hajamie

4
Хотя это не 100% точность, в большинстве случаев это достаточно хорошее решение. Спасибо за это - мне гораздо удобнее использовать это, чем большую функцию или сложное регулярное выражение из других решений.
Shane N

15

ВНИМАНИЕ! выбранный ответ содержит ошибку (ответ Жака).

если у вас более одного файла cookie (очень вероятно ..) и файл cookie, который вы извлекаете, является первым в списке, он не устанавливает переменную "end" и, следовательно, возвращает всю строку символов после "cookieName" = "в строке document.cookie!

вот исправленная версия этой функции:

function getCookie( name ) {
    var dc,
        prefix,
        begin,
        end;

    dc = document.cookie;
    prefix = name + "=";
    begin = dc.indexOf("; " + prefix);
    end = dc.length; // default to end of the string

    // found, and not in first position
    if (begin !== -1) {
        // exclude the "; "
        begin += 2;
    } else {
        //see if cookie is in first position
        begin = dc.indexOf(prefix);
        // not found at all or found as a portion of another cookie name
        if (begin === -1 || begin !== 0 ) return null;
    } 

    // if we find a ";" somewhere after the prefix position then "end" is that position,
    // otherwise it defaults to the end of the string
    if (dc.indexOf(";", begin) !== -1) {
        end = dc.indexOf(";", begin);
    }

    return decodeURI(dc.substring(begin + prefix.length, end) ).replace(/\"/g, ''); 
}

Установив всего один файл cookie, ваша функция вернула cookieName =. : - /
Jeppe

1
@Jeppe Я изменил код, чтобы он работал и при наличии только одного файла cookie. На самом деле я воспользовался шансом реорганизовать всю функцию и привести ее в порядок, а также добавить несколько комментариев. ;)
Пиккио

что-то не так с replace (/ "/ g, ''); это дает мне синтаксическую ошибку
iKamy

это сработало для меня, но, вероятно, лучше избегать кавычек в регулярном выражении. Я отредактировал ответ. Должен работать и для вас сейчас!
Pikkio

6

Если вы используете jQuery, вы можете использовать плагин jquery.cookie .

Получение значения для конкретного файла cookie выполняется следующим образом:

$.cookie('MyCookie'); // Returns the cookie value

3
Это также предполагает, что OP использует плагин jquery-cookie. Это ненадолго зациклило меня, поскольку я использовал jquery, но не могу использовать этот плагин для задачи, которую решал.
hippeelee

8
это не только относится к jquery, но также требует плагина jquery, на который вы не ссылались в своем ответе
artfulhacker

4

regexObject. test (String) быстрее, чем string.совпадение (RegExp).

На сайте MDN описан формат для document.cookie и есть пример регулярного выражения для получения cookie ( document.cookie.replace(/(?:(?:^|.*;\s*)test2\s*\=\s*([^;]*).*$)|^.*$/, "$1");). Исходя из этого, я бы пошел на это:

/^(.*;)?\s*cookie1\s*=/.test(document.cookie);

Вопрос, похоже, требует решения, которое возвращает false, когда cookie установлен, но пуст. В этом случае:

/^(.*;)?\s*cookie1\s*=\s*[^;]/.test(document.cookie);

Тесты

function cookieExists(input) {return /^(.*;)?\s*cookie1\s*=/.test(input);}
function cookieExistsAndNotBlank(input) {return /^(.*;)?\s*cookie1\s*=\s*[^;]/.test(input);}
var testCases = ['cookie1=;cookie1=345534;', 'cookie1=345534;cookie1=;', 'cookie1=345534;', ' cookie1 = 345534; ', 'cookie1=;', 'cookie123=345534;', 'cookie=345534;', ''];
console.table(testCases.map(function(s){return {'Test String': s, 'cookieExists': cookieExists(s), 'cookieExistsAndNotBlank': cookieExistsAndNotBlank(s)}}));

Результаты тестов (Chrome 55.0.2883.87)


как я могу передать переменную как cookieName вместо того, чтобы передавать cookieName как строку?
ДИЛИП ТОМАС

var name = 'cookie1'; новый RegExp ('^ (. *;)? \\ s *' + name + '\\ s * ='). test (document.cookie);
hajamie

4

Это старый вопрос, но вот подход, который я использую ...

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

Это возвращается nullлибо в том случае, если файл cookie не существует, либо если он не содержит запрошенного имени.
В противном случае возвращается значение (запрошенного имени).

Файл cookie никогда не должен существовать без ценности - потому что, честно говоря, какой в ​​этом смысл? 😄
Если это больше не нужно, лучше просто избавиться от всего этого вместе.

function deleteCookie(name) {
    document.cookie = name +"=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;";
}

У файла cookie без значения есть вполне веская причина - сигнализировать о существовании чего-либо. Он будет использоваться как логическое: cookie существует => истина, cookie не существует => ложь
Гас

2
Это был лучший метод в списке.
Эндрю

1
function getCookie(name) {

    var dc = document.cookie;
    var prefix = name + "=";
    var begin = dc.indexOf("; " + prefix);
    if (begin == -1) {
        begin = dc.indexOf(prefix);
        if (begin != 0) return null;
        else{
            var oneCookie = dc.indexOf(';', begin);
            if(oneCookie == -1){
                var end = dc.length;
            }else{
                var end = oneCookie;
            }
            return dc.substring(begin, end).replace(prefix,'');
        } 

    }
    else
    {
        begin += 2;
        var end = document.cookie.indexOf(";", begin);
        if (end == -1) {
            end = dc.length;
        }
        var fixed = dc.substring(begin, end).replace(prefix,'');
    }
    // return decodeURI(dc.substring(begin + prefix.length, end));
    return fixed;
} 

Пробовал функцию @jac, возникли проблемы, вот как я отредактировал его функцию.


1

вместо переменной cookie вы просто использовали бы document.cookie.split ...

var cookie = 'cookie1=s; cookie1=; cookie2=test';
var cookies = cookie.split('; ');
cookies.forEach(function(c){
  if(c.match(/cookie1=.+/))
   console.log(true);
});


1

Для всех, кто использует Node, я нашел хорошее и простое решение с импортом ES6 и cookie модулем!

Сначала установите модуль cookie (и сохраните как зависимость):

npm install --save cookie

Затем импортируйте и используйте:

import cookie from 'cookie';
let parsed = cookie.parse(document.cookie);
if('cookie1' in parsed) 
    console.log(parsed.cookie1);

1

Используя Javascript:

 function getCookie(name) {
      let matches = document.cookie.match(new RegExp(
        "(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
      ));
      return matches ? decodeURIComponent(matches[1]) : undefined;
    }

0

вместо этого используйте этот метод:

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

function doSomething() {
    var myCookie = getCookie("MyCookie");

    if (myCookie == null) {
        // do cookie doesn't exist stuff;
    }
    else {
        // do cookie exists stuff
    }
}

0
/// ************************************************ cookie_exists

/// global entry point, export to global namespace

/// <synopsis>
///   cookie_exists ( name );
///
/// <summary>
///   determines if a cookie with name exists
///
/// <param name="name">
///   string containing the name of the cookie to test for 
//    existence
///
/// <returns>
///   true, if the cookie exists; otherwise, false
///
/// <example>
///   if ( cookie_exists ( name ) );
///     {
///     // do something with the existing cookie
///     }
///   else
///     {
///     // cookies does not exist, do something else 
///     }

function cookie_exists ( name )
  {
  var exists = false;

  if ( document.cookie )
    {
    if ( document.cookie.length > 0 )
      {
                                    // trim name
      if ( ( name = name.replace ( /^\s*/, "" ).length > 0 ) )
        {
        var cookies = document.cookie.split ( ";" );
        var name_with_equal = name + "=";

        for ( var i = 0; ( i < cookies.length ); i++ )
          {
                                    // trim cookie
          var cookie = cookies [ i ].replace ( /^\s*/, "" );

          if ( cookie.indexOf ( name_with_equal ) === 0 )
            {
            exists = true;
            break;
            }
          }
        }
      }
    }

  return ( exists );

  } // cookie_exists

0

Здесь есть несколько хороших ответов. Я же предпочитаю [1] не с помощью регулярных выражений, и [2] , используя логику, легко читать, и [3] , чтобы иметь короткую функцию, [4] ничего не возвращает истину , если имя является подстрока другого печенья имя . Наконец [5] мы не можем использовать a для каждого цикла, поскольку возврат не прерывает его.

function cookieExists(name) {
  var cks = document.cookie.split(';');
  for(i = 0; i < cks.length; i++)
    if (cks[i].split('=')[0].trim() == name) return true;
}

0
function getcookie(name = '') {
    let cookies = document.cookie;
    let cookiestore = {};
    
    cookies = cookies.split(";");
    
    if (cookies[0] == "" && cookies[0][0] == undefined) {
        return undefined;
    }
    
    cookies.forEach(function(cookie) {
        cookie = cookie.split(/=(.+)/);
        if (cookie[0].substr(0, 1) == ' ') {
            cookie[0] = cookie[0].substr(1);
        }
        cookiestore[cookie[0]] = cookie[1];
    });
    
    return (name !== '' ? cookiestore[name] : cookiestore);
}

Чтобы получить объект cookie, просто позвоните getCookie()

Чтобы проверить, существует ли cookie, сделайте это следующим образом:

if (!getcookie('myCookie')) {
    console.log('myCookie does not exist.');
} else {
    console.log('myCookie value is ' + getcookie('myCookie'));
}

Или просто используйте тернарный оператор.


0
function hasCookie(cookieName){
return document.cookie.split(';')
.map(entry => entry.split('='))
.some(([name, value]) => (name.trim() === cookieName) && !!value);
}

Примечание. Автор хотел, чтобы функция возвращала false, если файл cookie пуст, т.е. cookie=;это достигается с помощью && !!valueусловия. Удалите его, если считаете, что пустой файл cookie все еще существует…


0

var cookie = 'cookie1=s; cookie1=; cookie2=test';
var cookies = cookie.split('; ');
cookies.forEach(function(c){
  if(c.match(/cookie1=.+/))
   console.log(true);
});


Привет и добро пожаловать в SO! Хотя этот код может ответить на вопрос, предоставление дополнительного контекста относительно того, как и / или почему он решает проблему, улучшит долгосрочную ценность ответа. Пожалуйста , прочитайте тур , и Как написать хороший ответ?
Томер Шетах

0

Обратите внимание, что если файл cookie безопасен, вы не можете проверить его существование на стороне клиента document.cookie(что используется во всех ответах). Такой cookie можно проверить только на стороне сервера.

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