Руководство по использованию API магазина файлов cookie

Руководство по использованию API магазина файлов cookie

29 апреля 2023 г.

Сегодня, просматривая список веб-API на MDN, я наткнулся на один что меня удивило — API магазина файлов cookie. Это явно помечено как экспериментальное (в настоящее время поддерживается только в Chrome/Edge), но выглядит увлекательно.

Файлы cookie — это самый старый (насколько мне известно) способ для веб-приложений хранить данные на клиенте. Они также, как правило, являются наименее рекомендуемым способом сделать это по многим, многим причинам.

Однако иногда вам нужно работать с файлами cookie, и это выглядит как действительно хороший новый способ работы с ними. Вот краткий обзор.

Старый способ

В течение последних нескольких сотен лет работа с файлами cookie в браузере включала синтаксический анализ строк. На самом деле не было даже «API». Вы бы прочитали document.cookie, который вернул строку значений cookie с разделителями:

'_ga=GA1.1.277504870.1615419234; ezux_ifep_238929=true; ezouspvh=1900; __qca=I0-1813545485-1623786777967; ezouspva=0; ezouspvv=0; ezux_et_238929=10099; ezux_tos_238929=5877205; _ALGOLIA=anonymous-c45533a4-0752-4b4d-90cb-b641b642cf4f; _ga_T5V3C8M5RY=GS1.1.1669062149.711.1.1669064843.0.0.0; hitCounter=0'

Чтобы получить конкретный файл cookie, вы должны проанализировать его с помощью точки с запятой, а затем разбить его на пары «имя-значение». Однако файлы cookie могут иметь больше, чем просто имя и значение. Например, у большинства файлов cookie есть срок действия. Но это не читается JavaScript.

Еще более странно то, что значение document.cookie представляет собой список всех файлов cookie, которые вы можете использовать:

document.cookie = 'name=val';

Написать одну куки, оставив остальные в покое. При написании файлов cookie вы можете установить дополнительные значения, например срок действия, с помощью точки с запятой. Вот пример из MDN:

document.cookie =
      "doSomethingOnlyOnce=true; expires=Fri, 31 Dec 9999 23:59:59 GMT; SameSite=None; Secure";

Из-за того, насколько это шатко, существуют библиотеки, чтобы упростить его. Раньше у MDN была хорошая небольшая библиотека для этого, но, к сожалению, похоже, она была удалена с их сайта.

К счастью, существует около десяти миллиардов других библиотек/утилит/простых функций JavaScript, которые вы могли бы использовать вместо этого. Или...

Блестящий новый путь

Итак, как я упоминал в начале, похоже, что у нас есть (или, надеюсь, будет) новый современный API для работы с файлами cookie. API магазина файлов cookie предоставляет асинхронный API для чтения, записи и удаления файлов cookie. Это также позволяет вам прослушивать изменения в файлах cookie.

Как упоминалось выше, в настоящее время это только совместимо с Chrome и Edge (хорошо , Опера и самсунг интернет тоже). Не знаю, добавит ли Safari это, и ваше предположение так же хорошо, как и мое.

Чтобы проверить наличие поддержки, вы можете найти объект cookieStorage:

if(!("cookieStore" in window)) {
    console.log('Not supported');
    return;
}

После того как вы подтвердите, что можете использовать его, вот несколько кратких примеров методов.

Получение файла cookie

Чтобы получить файл cookie, используйте get. Необычно, правда? Он поддерживает необязательную проверку области URL-адресов, обычно используемую на больших сайтах, чтобы ограничить доступность файла cookie только к его части. Вот самый простой пример:

let hitCounter = await cookieStore.get('hitCounter');

Как упоминалось ранее, API является асинхронным, поэтому вы можете либо ожидать его, либо использовать затем. Я предпочитаю await.

Если файл cookie не существует, вы получите ответ null; в противном случае такой объект:

{
    "domain": null,
    "expires": null,
    "name": "hitCounter",
    "path": "/",
    "sameSite": "strict",
    "secure": true,
    "value": "7"
}

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

Настройка файла cookie

Как вы понимаете, настроить файл cookie также довольно просто. Если вы хотите установить файл cookie и значение, вы просто делаете:

cookieStore.set('hitCounter', 9);

Это также будет асинхронным, поэтому либо await, либо обязательно используйте then. Обратите внимание, что даже если я передам число, при сохранении оно станет строкой. Если вы хотите установить параметры, используйте форму:

const tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);

cookieStore.set({
    name:'hitCounter',
    value:9, 
    expires:tomorrow
});

В этом примере я просто указал 24-часовую дату истечения срока действия в качестве опции, но есть и другие опции (проверьте set docs для списка).

Удаление файла cookie

Опять же, еще один простой API, но помните, что он асинхронный:

cookieStore.delete('nameOfCookie');

Также есть такая опция, как get, где вы можете передать объект, содержащий дополнительные параметры. Хорошим примером здесь может быть path, и опять же, подумайте о большом веб-сайте, которому необходимо убедиться, что файл cookie с именем foo в пути не мешает другому файлу cookie.

Cookie Monster (он же All the Cookies)

Последний метод, который я покажу, — это метод getAll, который возвращает массив файлов cookie. Запуск cookieStore.getAll().then(console.log) в моем блоге возвращает:

Прослушивание событий cookie

Одним из интересных аспектов API является возможность запускать код при изменении файлов cookie. Так, например:

cookieStore.onchange = (event) => {
    console.log('cookie change event', event);
};

Это вызывает событие CookieChangeEvent. Это событие содержит несколько интересных свойств:

* type сообщит вам тип изменения: удалено или изменено.

* changed — это массив файлов cookie, которые были изменены.

* deleted — это массив файлов cookie, которые были удалены.

В документах для события не указано, почему changed и deleted являются массивом, но если бы мне пришлось догадываться, из-за асинхронного характера API можно было бы изменить/удалить N файлов cookie, прежде чем событие сможет сработать в ответ; следовательно, нужны результаты в массиве.

Пример

Хотя в целом я бы не рекомендовал использовать файлы cookie для новых проектов, я сделал невероятно простую демонстрацию, которая отслеживает количество посещений вами сайта. Для этого используется файл cookie hitCounter. Во-первых, HTML:

<h2>Cookie Store Demo 1</h2>

<p>
    You have been to this page <span id="hitCount"></span> time(s).
</p>

А затем JavaScript:

document.addEventListener('DOMContentLoaded', init, false);
async function init() {
    if(!("cookieStore" in window)) {
        console.log('Not supported');
        return;
    }

    cookieStore.onchange = (event) => {
        console.log('cookie change event', event);
    };

    let hitCounter = await cookieStore.get('hitCounter');

    if(!hitCounter) {
        hitCounter = { value: 0 }
    }

    hitCounter.value = parseInt(hitCounter.value,10)+1;

    try {
        await cookieStore.set('hitCounter', hitCounter.value);

        /*
        const tomorrow = new Date();
        tomorrow.setDate(tomorrow.getDate() + 1);

        cookieStore.set({
        name:'hitCounter',
        value:hitCounter.value, 
        expires:tomorrow
        });
        */
    } catch(e) {
        console.error(e);
    }

    document.querySelector('#hitCount').innerText = hitCounter.value;

}

По сути, прочитайте файл cookie, и, если он нулевой, по умолчанию будет равен 0. Затем добавьте к нему единицу после синтаксического анализа в целое число и сохраните значение. Теоретически мне не нужно await; Я мог бы просто запустить и забыть и немедленно обновить DOM, но вы поняли идею.

Я также оставил в комментариях «только 24-часовую версию» просто для справки. Вы можете протестировать эту демонстрацию здесь: https://respected-periwinkle-warlock.glitch.me и просмотреть код здесь. : https://glitch.com/edit/#!/respected-periwinkle-warlock.< /p>

Прежде чем двигаться дальше, краткое примечание о try/catch. Браузер может блокировать запись в куки, и если это так, вы получите сообщение об ошибке:

Error: An unknown error occurred while writing the cookie.

Если вы заботитесь об этом в своем приложении, обратите внимание на ошибку.


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE