Założenia
Na podstawie pytania uważam, że niektóre założenia / wymagania dotyczące tej funkcji obejmują:
- Będzie on używany jako funkcja biblioteki , a więc przeznaczony do umieszczenia w dowolnej bazie kodu;
- Jako taki będzie musiał działać w wielu różnych środowiskach , tj. Pracować ze starszym kodem JS, CMS o różnych poziomach jakości itp .;
- Aby współpracować z kodem napisanym przez inne osoby i / lub kodem, którego nie kontrolujesz, funkcja nie powinna przyjmować żadnych założeń dotyczących sposobu kodowania nazw lub wartości plików cookie . Wywołanie funkcji za pomocą łańcucha
"foo:bar[0]"
powinno zwrócić plik cookie (dosłownie) o nazwie „foo: bar [0]”;
- Nowe pliki cookie mogą być zapisywane i / lub istniejące pliki cookie modyfikowane w dowolnym momencie życia strony.
Zgodnie z tymi założeniami jasne jest, że encodeURIComponent
/ decodeURIComponent
nie należy używać ; Robiąc to, zakłada się, że kod, który ustawia plik cookie, również koduje go przy użyciu tych funkcji.
Metoda wyrażeń regularnych staje się problematyczna, jeśli nazwa pliku cookie może zawierać znaki specjalne. jQuery.cookie rozwiązuje ten problem, kodując nazwę pliku cookie (w rzeczywistości zarówno nazwę, jak i wartość) podczas przechowywania pliku cookie oraz dekodując nazwę podczas pobierania pliku cookie. Rozwiązanie wyrażeń regularnych znajduje się poniżej.
O ile nie czytasz tylko plików cookie, które kontrolujesz całkowicie, wskazane byłoby również odczytywanie plików cookie document.cookie
bezpośrednio i nie buforowanie wyników, ponieważ nie ma sposobu, aby dowiedzieć się, czy pamięć podręczna jest nieprawidłowa bez document.cookie
ponownego czytania .
(Podczas gdy uzyskiwanie dostępu i parsowanie document.cookies
będzie nieco wolniejsze niż w przypadku użycia pamięci podręcznej, nie będzie tak wolne jak czytanie innych części DOM, ponieważ pliki cookie nie odgrywają roli w drzewach DOM / renderowania).
Funkcja oparta na pętli
Oto odpowiedź Code Golf, oparta na funkcji PPK (pętli):
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, '');
}
który po zminimalizowaniu ma 128 znaków (nie licząc nazwy funkcji):
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,'');}
Funkcja oparta na wyrażeniach regularnych
Aktualizacja: jeśli naprawdę potrzebujesz rozwiązania wyrażeń regularnych:
function readCookie(name) {
return (name = new RegExp('(?:^|;\\s*)' + ('' + name).replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') + '=([^;]*)').exec(document.cookie)) && name[1];
}
Pozwala to uniknąć znaków specjalnych w nazwie pliku cookie przed zbudowaniem obiektu RegExp. Zminimalizowane, zawiera 134 znaki (nie licząc nazwy funkcji):
function readCookie(n){return(n=new RegExp('(?:^|;\\s*)'+(''+n).replace(/[-[\]{}()*+?.,\\^$|#\s]/g,'\\$&')+'=([^;]*)').exec(document.cookie))&&n[1];}
Jak zauważyli Rudu i cwolves w komentarzach, wyrażenie regularne uciekające od wyrażenia regularnego można skrócić o kilka znaków. Myślę, że dobrze byłoby zachować spójność uciekającego wyrażenia regularnego (być może używasz go gdzie indziej), ale ich sugestie są warte rozważenia.
Notatki
Obie te funkcje nie będą obsługiwać null
lub undefined
, tj. Jeśli istnieje plik cookie o nazwie „null”, readCookie(null)
zwróci jego wartość. Jeśli musisz poradzić sobie z tą sprawą, odpowiednio dostosuj kod.