Cookie

Время чтения: меньше 5 мин

Кратко

Секция статьи "Кратко"

При разработке сайтов часть информации (например, токен авторизации или данные пользователя) нужно хранить и читать как в браузере, так и на сервере. Для этого используют Cookie (произносится «куки»).

Как пользоваться

Секция статьи "Как пользоваться"

Все куки хранятся в поле document.cookie. Это поле представляет из себя строку в формате имя=значение, где имя и значение разделяются знаком ; . При этом взаимодействие с полем весьма необычное — если присвоить document.cookie новое значение, то оно не заменит полностью старую строку, а добавит или изменит значение по ключу.

Запись

Секция статьи "Запись"

Запись в cookie работает с помощью присвоения значения новой cookie в поле document.cookie. За один раз можно записать лишь одно значение.
Добавление нового значения работает следующим образом:

        
          
          document.cookie = "counter=1"; // -> "counter=1"
          document.cookie = "counter=1"; // -> "counter=1"

        
        
          
        
      

Предположим, что до этого у нас не было установлено никаких кук. И при повторном присвоении куки с другим именем, мы получим два записанных значения.

        
          
          document.cookie = "sidebar=false"; // -> "counter=1; sidebar=false;"
          document.cookie = "sidebar=false"; // -> "counter=1; sidebar=false;"

        
        
          
        
      

При повторной записи в то же поле другого значения оно будет перезаписано.

        
          
          document.cookie = "sidebar=true"; // -> "counter=1; sidebar=true;"
          document.cookie = "sidebar=true"; // -> "counter=1; sidebar=true;"

        
        
          
        
      

При установке cookie можно указывать не только её название и значение, но и другие параметры, все они являются необязательными и разделяются точкой с запятой ;

  • path – определяет путь, по которому будет доступна кука. Он должен быть абсолютным, то есть начинаться с /. Если параметр не передан, то кука будет доступна на всех страницах сайта.
  • domain - определяет домен, для которого указана кука. Если не указано, то будет использоваться текущий домен.
  • max-age и expires - определяет время жизни куки.max-age указывает, через сколько секунд, а expires указывает точное время, когда кука станет недействительна. Время для expires можно отформатировать с помощью встроенного метода даты Date.toUTCString()
  • secure - указывает, что данная кука может быть передана только при запросах по защищённому протоколу HTTPS.
  • samesite - определяет, может ли данная кука быть отправлена при кросс-доменном запросе. Значение параметра strict будет предотвращать отправку на другие домены, а lax разрешит отправлять куки с GET-запросами.

Запись куки с разрешением передавать её только по HTTPS и только для текущего домена, со временем жизни в 1 час будет выглядеть так:

        
          
          document.cookie = "sidebar=true;secure;samesite=strict;max-age=3600";
          document.cookie = "sidebar=true;secure;samesite=strict;max-age=3600";

        
        
          
        
      
Все возможные параметры установки куки

Чтение

Секция статьи "Чтение"

Для получения значений, записанных в cookie, можно просто вывести содержимое document.cookie:

        
          
          console.log(document.cookie);
          console.log(document.cookie);

        
        
          
        
      

Учитывая, что мы уже дважды записывали cookie, при вызове команды выше в консоли выведется counter=1; sidebar=true;.

Чтобы получить значение конкретной cookie, нам нужно будет прочитать строки и разобрать её по значениям. Например так:

        
          
          function getCookie() {  return document.cookie.split("; ").reduce((acc, item) => {    const [name, value] = item.split("=");    return { ...acc, [name]: value };  }, {});}const cookie = getCookie();console.log(cookie.counter);console.log(cookie.sidebar);
          function getCookie() {
  return document.cookie.split("; ").reduce((acc, item) => {
    const [name, value] = item.split("=");

    return { ...acc, [name]: value };
  }, {});
}

const cookie = getCookie();

console.log(cookie.counter);
console.log(cookie.sidebar);

        
        
          
        
      

Удаление

Секция статьи "Удаление"

Для кук не предусмотрено специального метода удаления, поэтому для этого используется трюк с установкой кук с параметром expires который указывает на дату в прошлом. Браузер сразу же считает такую куку устаревшей и удаляет её:

        
          
          document.cookie = `sidebar=;expires=${new Date(0)}`;
          document.cookie = `sidebar=;expires=${new Date(0)}`;

        
        
          
        
      

В этом примере, передав число 0 в конструктор Date мы получаем время на начало эпохи Unix, а именно 1 января 1970 г. Поскольку эта дата из прошлого, то кука будет удалена моментально.

На практике

Секция статьи "На практике"

Павел Минеев

Секция статьи "Павел Минеев"

Есть куки, которые нельзя прочитать или записать из JavaScript. Если сервер устанавливает куки с параметром HttpOnly (доступен только для установки сервером), то такие cookie будут недоступны в document.cookie. Как правило, такие куки используются для хранения чувствительной информации, как, например, токены для авторизации. Проверка авторизации происходит с помощью запроса с текущим авторизованным пользователем и считается при успешном ответе сервера.

kamyshev

Секция статьи "kamyshev"

Формат строки document.cookie не очень удобен для работы, поэтому обычно в проекте создают функции, которые упрощают чтение и запись кук. Чтобы не писать эти функции самостоятельно, можно взять библиотеку js-cookie — это совсем небольшая обёртка над стандартным браузерным API, которая здорово упрощает жизнь.

С этой библиотекой установка значения для куки выполняется так:

        
          
          import Cookies from "js-cookie";Cookies.set("foo", "bar");
          import Cookies from "js-cookie";

Cookies.set("foo", "bar");

        
        
          
        
      

А чтение так:

        
          
          import Cookies from "js-cookie";const nameFromCookie = Cookies.get("name");
          import Cookies from "js-cookie";

const nameFromCookie = Cookies.get("name");

        
        
          
        
      

Конечно, под капотом эта библиотека тоже работает с document.cookie, но снаружи она предоставляет простой и удобный интерфейс.