Jak sprawdzić, czy plik cookie istnieje?


84

Jaki jest dobry sposób sprawdzenia, czy plik cookie istnieje?

Warunki:

Plik cookie istnieje, jeśli

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

Plik cookie nie istnieje, jeśli

cookie=;
//or
<blank>

Odpowiedzi:


127

Możesz wywołać funkcję getCookie z nazwą pliku cookie, który chcesz, a następnie sprawdzić, czy jest = 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
Ponieważ unescapejest przestarzałe, czy jest jakaś różnica przy użyciu decodeURIComponentzamiast tego?
the_nuts

3
@the_nuts, Niezły chwyt. Nie wiedziałem tego. Według w3cschools decodeURI () lub decodeURIComponent może być użyte do zastąpienia unescape. Wybór, którego użyć, może sprowadzać się do tego, co jest przechowywane, wybrałem decodeURI, ponieważ nie spodziewam się, że w pliku cookie będę miał zakodowane znaki separatora. Pełne odniesienie: w3schools.com/jsref/jsref_decodeuri.asp
jac

3
to nie działa z pierwszym ciasteczkiem, ponieważ zmienny koniec nie jest ustawiony
warch

funkcja doSomething ($ name) {var myCookie = getCookie ($ name);
Sol

1
To doskonały przykład, dlaczego w3schools nie jest wiarygodnym źródłem i dlaczego nie powinieneś kopiować / wklejać z niego odpowiedzi. Uniknąłbyś używania == i! =, Które są dość dobrze znane w js.
Isaac Pak

96

Stworzyłem alternatywną wersję inną niż jQuery:

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

Sprawdza tylko, czy istnieje plik cookie. Bardziej skomplikowana wersja może również zwracać wartość cookie:

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

Umieść swoją nazwę pliku cookie w miejsce MyCookie.


14
wspaniałe czyste rozwiązanie! W dzisiejszych czasach ludzie pobierają wtyczki zbyt szybko ... za dużo. To bardzo fajne rozwiązanie!
patrick

3
To nie działa. W Regexie brakuje spacji. Powinien to być document.cookie.match (/^(.*;)? MyCookie = [^;] + (. *)? $ /), Zwróć uwagę na spację po?.
Bogdan M.

1
document.cookie zwraca ciasteczka oddzielone spacjami, np .: cookie1 =; cookie1 = 345534;
Bogdan M.

1
@BogdanM. : Brak miejsca na pierwszy plik cookie! / [] {0,1} / Zobacz mój komentarz powyżej
Gabriel,

6
Jeśli chcesz użyć zmiennej: new RegExp ("^ (?:. *;)? \\ s *" + cookieName + "\\ s * = \\ s * ([^;] +) (?:. *)? $ ")
josef

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

Zwróci, -1jeśli ten plik cookie nie istnieje.

ps Jedyną wadą jest to (jak wspomniałem w komentarzach), że pomyli się, jeśli istnieje plik cookie o takiej nazwie: any_prefix_cookie_name

( Źródło )


5
To również pasuje do wszystkich plików cookie, które mają ciąg znaków w nazwie. Np. Przykład zwraca coś innego niż -1jeśli cookie_name_whateverjest ustawione (nawet jeśli nazwa_pliku cookie nie jest). Wersja wyrażenia regularnego w innej odpowiedzi rozwiązuje ten problem.
hajamie

4
Chociaż nie jest to w 100% dokładne, w większości przypadków jest to wystarczająco dobre rozwiązanie. Dzięki za to - czuję się dużo bardziej komfortowo, używając tego niż dużej funkcji lub skomplikowanego wyrażenia regularnego z innych rozwiązań.
Shane N,

14

UWAGA! wybrana odpowiedź zawiera błąd (odpowiedź Jaca).

jeśli masz więcej niż jeden plik cookie (bardzo prawdopodobne ...) i plik cookie, który pobierasz, jest pierwszy na liście, nie ustawia zmiennej „end” i dlatego zwróci cały ciąg znaków następujący po „cookieName” = "w ciągu document.cookie!

tutaj jest poprawiona wersja tej funkcji:

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, ''); 
}

Po ustawieniu tylko jednego pliku cookie funkcja zwróciła „cookieName =”. : - /
Jeppe

1
@Jeppe Zmodyfikowałem kod tak, aby działał, gdy jest tylko jeden plik cookie. Skorzystałem z okazji, aby zrefaktoryzować całą funkcję i uporządkować ją, a także dodać kilka komentarzy. ;)
Pikkio

coś jest nie tak z
funkcją

u mnie zadziałało, ale prawdopodobnie lepiej jest unikać cudzysłowów w wyrażeniu regularnym. Poprawiłem odpowiedź. Teraz też powinien działać dla Ciebie!
Pikkio

6

Jeśli używasz jQuery, możesz użyć wtyczki jquery.cookie .

Pobieranie wartości dla konkretnego pliku cookie odbywa się w następujący sposób:

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

3
To również zakłada, że ​​OP używa wtyczki jquery-cookie. Rzuciło mi to na chwilę pętlę, ponieważ używałem jquery, ale nie mogę użyć tej wtyczki do zadania, które rozwiązałem.
hippeelee

8
jest to nie tylko specyficzne dla jquery, ale także wymaga wtyczki jquery, do której nie
odwołałeś się

4

regexObject. test (String) jest szybszy niż string. dopasowanie (RegExp).

Witryna MDN opisuje format pliku document.cookie i zawiera przykładowe wyrażenie regularne do pobierania pliku cookie ( document.cookie.replace(/(?:(?:^|.*;\s*)test2\s*\=\s*([^;]*).*$)|^.*$/, "$1");). Na tej podstawie wybrałbym to:

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

Pytanie wydaje się prosić o rozwiązanie, które zwraca fałsz, gdy plik cookie jest ustawiony, ale pusty. W tym wypadku:

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

Testy

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

Wyniki testu (Chrome 55.0.2883.87)


jak mogę przekazać zmienną jako cookieName, zamiast przekazywać plik cookieName jako ciąg?
DILEEP THOMAS

var name = 'cookie1'; nowe RegExp ('^ (. *;)? \\ s *' + name + '\\ s * ='). test (document.cookie);
hajamie

4

To stare pytanie, ale oto podejście, które stosuję ...

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

Zwraca nullto, gdy plik cookie nie istnieje lub nie zawiera żądanej nazwy.
W przeciwnym razie zwracana jest wartość (żądanej nazwy).

Ciasteczko nie powinno nigdy istnieć bez wartości - bo, szczerze mówiąc, jaki to ma sens? 😄
Jeśli nie jest już potrzebny, najlepiej pozbyć się go razem.

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

Istnieje całkowicie uzasadniony powód, dla którego plik cookie nie ma wartości, czyli sygnalizuje istnienie czegoś. Byłoby używane jak wartość logiczna: plik cookie istnieje => prawda, plik cookie nie istnieje => fałsz
Gus

2
To była najlepsza metoda na liście.
Andrew

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

Wypróbowałem funkcję @jac, miałem problemy, oto jak edytowałem jego funkcję.


1

zamiast zmiennej cookie użyłbyś po prostu 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

Dla każdego, kto używa Node, znalazłem ładne i proste rozwiązanie z importem ES6 i cookiemodułem!

Najpierw zainstaluj moduł cookie (i zapisz jako zależność):

npm install --save cookie

Następnie zaimportuj i użyj:

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

1

Korzystanie z JavaScript:

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

0

zamiast tego użyj tej metody:

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

Jest tutaj kilka dobrych odpowiedzi. Ja jednak wolę [1] nie za pomocą wyrażenia regularnego, a [2] za pomocą logiki, która jest prosta do odczytania, a [3] , aby mieć krótkie funkcję [4] ma nie zwróci true, jeśli nazwa jest podciąg z innego pliku cookie Nazwa . Na koniec [5] nie możemy użyć for każdej pętli, ponieważ powrót jej nie przerywa.

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

Aby otrzymać obiekt ciasteczek wystarczy zadzwonić getCookie()

Aby sprawdzić, czy plik cookie istnieje, zrób to w następujący sposób:

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

Lub po prostu użyj operatora trójskładnikowego.


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

Uwaga: autor chciał, aby funkcja zwracała fałsz, jeśli plik cookie jest pusty, czyli cookie=;jest to osiągane z && !!valuewarunkiem. Usuń go, jeśli uważasz, że pusty plik cookie nadal istnieje ...


0

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


Witam i zapraszam do SO! Chociaż ten kod może odpowiedzieć na pytanie, dostarczenie dodatkowego kontekstu dotyczącego tego, jak i / lub dlaczego rozwiązuje problem, poprawiłoby długoterminową wartość odpowiedzi. Przeczytaj prezentację i jak napisać dobrą odpowiedź?
Tomer Shetah

0

Zauważ, że jeśli plik cookie jest bezpieczny, nie możesz sprawdzić po stronie klienta, czy istnieje, używając document.cookie(którego używają wszystkie odpowiedzi). Taki plik cookie można sprawdzić tylko po stronie serwera.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.