В основе работы localForage лежит идея унифицированного асинхронного API поверх различных механизмов хранения данных в браузере: IndexedDB, WebSQL и localStorage. Независимо от выбранного драйвера, данные проходят этап сериализации при записи и десериализации при чтении. Именно этот слой преобразования становится источником целого класса ошибок, связанных не с самим хранилищем, а с форматом данных и особенностями их преобразования.
Сериализация в контексте localForage почти всегда опирается на
JSON.stringify, а десериализация — на
JSON.parse. Это накладывает строгие ограничения на типы
данных и их структуру.
Перед записью любое значение преобразуется в строку:
При чтении происходит обратное преобразование:
null (в
зависимости от драйвера и сценария)Ключевая особенность: localForage не хранит «живые» JavaScript-объекты, он хранит их сериализованные представления.
JSON не поддерживает ряд встроенных типов Jav * aScript:
DateMapSetundefinedSymbolКаждый из этих типов либо преобразуется в упрощённое представление, либо полностью теряется.
const value = { created: new Date() };
После сериализации:
{"created":"2026-06-03T12:00:00.000Z"}
После десериализации это уже строка, а не объект
Date.
{
a: undefined,
b: () => {}
}
После сериализации поля будут удалены:
{}
new Map([["a", 1]])
Преобразуется в объект или теряет структуру в зависимости от предварительной обработки, но исходная семантика полностью утрачивается.
Если в хранилище попадает строка, не соответствующая JSON, возникает ошибка:
Типичный сценарий:
localStorage.setItem("key", "{invalid json}");
При чтении через localForage:
JSON.parse выбрасывает исключение
SyntaxErrorJSON не поддерживает циклы:
const a = {};
a.self = a;
При попытке записи через localForage:
JSON.stringify выбрасывает
TypeError: Converting circular structure to JSONЭто одна из самых частых причин падения записи сложных объектов.
При обновлении приложения структура данных часто меняется:
При десериализации старых данных возникают логические ошибки, а не синтаксические.
Пример:
Старая версия:
{ userId: 1 }
Новая версия ожидает:
{ user: { id: 1 } }
localForage корректно возвращает данные, но приложение получает несовместимый формат.
Хотя сериализация едина, поведение при ошибках отличается:
JSON.parseundefined без явной ошибкиВ IndexedDB возможны ситуации, когда:
Результат:
nulllocalForage позволяет переопределять драйверы и использовать собственные механизмы хранения. В таких случаях часто возникают ошибки:
encode(value) → string
decode(value) → object
Если функции не симметричны:
При попытке сериализовать:
ArrayBufferBlobчерез JSON:
Хотя JSON поддерживает Unicode, проблемы возникают на уровне:
Пример:
"?" // символ вне BMP
При неверной обработке может:
\uD834\uDF06При работе с большими объектами:
JSON.stringify может вызывать лагиRangeError: Invalid string lengthlocalForage в этом случае лишь усиливает эффект, поскольку добавляет слой абстракции поверх синхронного сериализатора.
Даже при успешной десериализации возможны ошибки типов:
null (при частичном повреждении)Это приводит к скрытым runtime-ошибкам:
undefined is not a functionCannot read property of nullПри обновлении логики приложения часто меняется:
Если старые данные не мигрированы:
Типичный сценарий:
Для минимизации проблем используются следующие подходы:
Ошибки сериализации и десериализации в localForage можно разделить на три группы:
Синтаксические ошибки
Семантические ошибки
Драйвер-специфические ошибки