Клавиша / esc

.cookie

Единственный доступ в банку с оставленными сервером печеньками.

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

Кратко

Скопировано

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

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

Скопировано

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

Запись

Скопировано

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

Вот так можно добавить значение 1 по ключу counter:

        
          
          document.cookie = 'counter=1'console.log(document.cookie)// 'counter=1'
          document.cookie = 'counter=1'
console.log(document.cookie)
// 'counter=1'

        
        
          
        
      

При присвоении свойству куки с другим именем, получим два записанных значения:

        
          
          document.cookie = 'sidebar=false'console.log(document.cookie)// 'counter=1; sidebar=false;'
          document.cookie = 'sidebar=false'
console.log(document.cookie)
// 'counter=1; sidebar=false;'

        
        
          
        
      

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

        
          
          document.cookie = 'sidebar=true'console.log(document.cookie)// -> 'counter=1; sidebar=true;'
          document.cookie = 'sidebar=true'
console.log(document.cookie)
// -> 'counter=1; sidebar=true;'

        
        
          
        
      

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

  • 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'

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

Чтение

Скопировано

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

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

        
        
          
        
      

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

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

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

const cookie = getCookie()

console.log(cookie.counter)
// 1
console.log(cookie.sidebar)
// true

        
        
          
        
      

Удаление

Скопировано

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

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

        
        
          
        
      

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

На практике

Скопировано

Павел Минеев советует

Скопировано

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

Игорь Камышев советует

Скопировано

Формат строки 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, но снаружи она предоставляет простой и удобный интерфейс.