Як мені перевірити, чи існує файл 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
warch

функція 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. : Немає місця для першого печива! / [] {0,1} / Див. Мій коментар вище
Габріель

6
Якщо ви хочете використовувати змінну: new RegExp ("^ (?:. *;)? \\ s *" + cookieName + "\\ s * = \\ s * ([^;] +) (?:. *)? $ ")
josef

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

Повернеться -1 якщо цього файлу cookie не існує.

ps Єдиним недоліком цього є (як згадувалося в коментарях) те, що він помилиться, якщо встановлений файл cookie з такою назвою: any_prefix_cookie_name

( Джерело )


5
Це також відповідає будь-яким файлам cookie із рядком у їх назві. Наприклад, приклад повертає щось інше, ніж -1якщо cookie_name_whateverвстановлено (навіть якщо cookie_name не вказано). Версія регулярного виразу в іншій відповіді це вирішує.
хаджамі

4
Хоча це не на 100% точність, це в більшості випадків є досить хорошим рішенням. Дякую за це - я почуваюся набагато комфортніше, використовуючи це, ніж велика функція або складний регулярний вираз з інших рішень.
Шейн Н

15

УВАГА! обрана відповідь містить помилку (відповідь Жака).

якщо у вас є більше одного файлу cookie (дуже ймовірно ..), і файл cookie, який ви отримуєте, є першим у списку, він не встановлює змінну "кінець", і тому він поверне цілий рядок символів після "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 =". : - /
Джеппе

1
@Jeppe Я змінив код так, щоб він працював, коли є лише один файл cookie. Я насправді скористався шансом переформатувати всю функцію та привести її в порядок, а також додавши деякі коментарі. ;)
Піккіо

щось не так із replace (/ "/ g, ''); це видає мені синтаксичну помилку
iKamy

це спрацювало для мене, але, мабуть, краще уникати цитат у регулярному виразі. Я відредагував відповідь. Має працювати і для вас зараз!
Піккіо

6

Якщо ви використовуєте jQuery, ви можете використовувати плагін jquery.cookie .

Отримання значення для певного файлу cookie виконується наступним чином:

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

3
Це також передбачає, що OP використовує плагін jquery-cookie. Це трохи кинуло мене на цикл, оскільки я використовував jquery, але не можу використовувати цей плагін для завдання, яке я вирішував.
hippeelee

8
це не тільки специфічно для jquery, але також вимагає плагін jquery, на який ви не
посилалися

4

regexObject. test (String) швидший за рядок. збіг (RegExp).

Сайт MDN описує формат документа.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 як рядок?
DILEEP THOMAS

var name = 'cookie1'; новий RegExp ('^ (. *;)? \\ s *' + ім'я + '\\ s * ='). тест (document.cookie);
хаджамі

4

Це старе питання, але ось підхід, який я використовую ...

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

Це повертається nullабо тоді, коли файл cookie не існує, або коли він не містить запитуваного імені.
В іншому випадку повертається значення (запитуваного імені).

Печиво ніколи не повинно існувати без цінності - адже, чесно кажучи, який сенс у цьому? 😄
Якщо це більше не потрібно, найкраще просто позбутися від усього разом.

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

Існує цілком обґрунтована причина того, щоб мати cookie без значення, тобто сигналізувати про існування чогось. Він використовувався б як логічний: cookie існує => true, cookie не існує => false
Gus

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 все ще є існуючим файлом 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.