.cookie

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

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

Cookie — один из способов хранить данные в браузере. Обзор всех способов хранения описан в статье «Хранение данных в браузере».

Кратко

Скопировано

При разработке сайтов часть информации (например, токен авторизации или данные пользователя) нужно хранить и читать как в браузере, так и на сервере. Для этого используют 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-запросами.

Есть пара ограничений при специфичных названиях кук. Если название куки начинается с __Secure-, то обязательно должен быть передан параметр secure. При этом мы должны находиться на странице, которая была получена по HTTPS-протоколу. Если название куки начинается с __Host-, то обязательно должны быть переданы параметры path=/ и secure (страница также должна быть открыта по HTTPS-протоколу), а атрибут domain должен отсутствовать для снижения кроссдоменных уязвимостей.

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