На сайтах этого типа реализована функция хранения каких либо файлов
Первоначально данная статья была размещена на Хабре, но по комментариям в нее были внесены некоторые дополнения, развивающие и объясняющие идеи, изложенные в статье.
За последнее время мне пришлось активно работать с сайтами, которые большие объемы информации хранят в файловой системе. Это разнообразные сайты фото и файловых хостингов, а также сайты с загрузкой видео контента, некоторые сайты проектировались и программировались мной с нуля, некоторые переписывались, дописывались или "приводились в порядок".
Должен отметить, что хранение файлов в файловой системе является для многих программистов областью, которая проходит мимо их внимания.
Для начала дам небольшой обзор распространенных ошибок:
1. файл храниться в файловой системе под кириллическим названием. Собственно, происходит следующее: пользователь загружает файл под именем, скажем, "безымянный-1.jpg", программист с тем же именем запихивает его в каталог, в котором хранятся файлы. Надеюсь, не нужно объяснять какие проблемы это за собой может повлечь?
2. файл храниться под тем же названием, под которым он был загружен пользователем, но символы не входящие в латинский алфавит транслитерированы. Уже лучше, но все равно данный способ вызывает множество проблем, например, пользователи очень любят грузить файлы с одинаковыми названиями))) И дело не в том, что они такие злые, например мой фотоаппарат после каждой очистки карты памяти начинает нумерацию фотографий с 00001.
И третья самая распространенная ошибка:
3. Хранение в директории количества файлов превышающих возможности файловой системы. Рассмотрим эту ситуацию на конкретном примере, переписывал я как-то файловый хостинг, большой, на момент переписывания объем информации вплотную приближался к четырем терабайтам, и это притом, что 80 процентов файлов были картинками. Все файлы на диске (дисков было 4 каждый по терабайту) случайным образом раскидывались по двум десяткам директорий, и так до заполнения диска, потом программа переходила на следующий диск. В результате для того что бы открыть директорию вебсерверу требовалось около трех секунд. Согласитесь, это катастрофически много. В каждой директории на диске находилось около двадцати тысяч файлов.
Проанализировав несколько таких ситуаций, я попробовал создать способ хранения файлов, который бы удовлетворял следующим условиям:
1. директория не должна «тормозить», то есть в одной директории не должно храниться более 1000 файлов или каталогов (число взято с запасом). По данному пункту напомню, что каталог файловой системы, можно рассматривать как файл со списком файлов, которые находятся в этом каталоге. Имея полный путь к файлу, мы должны просмотреть последовательно несколько файлов «каталогов», для того, что бы в последнем найти физический адрес (первый кластер нужного нам файла). Естественно, чем больше в каждом каталоге файлов и вложенных каталогов, тем больше времени занимает данная операция. Идеально, что бы весь список файлов содержащихся в одном каталоге, помещался в одном кластере на диске, что бы головка винчестера могла прочитать данный «файл-каталог» в «одно касание».
2. Имена файлов не должны повторяться. Наверное, данный пункт даже расшифровывать не нужно - одинаковые имена совсем не говорят об одинаковом содержимом и наоборот.
3. Желательно не хранить две копии одного файла. Это не является большой проблемой, если мы храним картинки (хотя как сказать… пара тысяч повторяющихся картинок в хорошем качестве и пяти гигабайт как не бывало). Но при хранении на диске чего то более серьезного по объему повторяющиеся файлы уже являются большой проблемой (например, три четыре одинаковых дистрибутива линукса.
После некоторых раздумий, я пришел к следующей схеме, которой и хочу поделиться с коллегами программистами.
Начну с последнего требования не хранить две копии файла. Для определения целостности файла давно и вполне успешно используется md5 хеш для php, эта задача решается функцией md5_file(filename), которая вычисляет MD5 хэш файла, имя которого задано аргументом filename используя алгоритм MD5 RSA Data Security, Inc. и возвращает этот хэш. Хэш представляет собой 32-значное шестнадцатеричное число.
Если два файла одинаковы у них и хеш будет одинаков, если разные - то разный. Сейчас в меня «полетят камни» сопровождающиеся рассуждениями о коллизиях и ненадежности md5. Отвечу по порядку md5 не надежна? Но мы же не ставим задачу обмануть «вероятного противника»! Мы просто получаем уникальный идентификатор файла и все. А по поводу коллизий. я не настаиваю на повторении моего метода один в один, используйте другую функцию. Только задумайтесь, два в двести пятьдесят шестой степени это - очень много! Если мне говорят, про возможность возникновения коллизий, я прошу человека привести пример двух строк или двух файлов, md5 хеш, которых одинаков. пока еще мне не было приведено такой пары так, что возможность является чисто теоретической. Однако в комментариях на хабре мне привели две строки, которые дают одинаковый md 5 хеш, что же один вариант возникновения коллизий теперь известен. Однако не предполагаю, что на практике это имеет действительно большое значение.
В качестве примера приведу обе строки:
d131dd02c5e6eec4693d9a0698aff95c2fcab58712467eab4004583eb8fb7f8955ad340609f4b30283e488832571415a
085125e8f7cdc99fd91dbdf280373c5bd8823e3156348f5bae6dacd436c919c6dd53e2b487da03fd02396306d248cda0
e99f33420f577ee8ce54b67080a80d1ec69821bcb6a8839396f9652b6ff72a70
d131dd02c5e6eec4693d9a0698aff95c2fcab5 O 712467eab4004583eb8fb7f8955ad340609f4b30283e4888325f1415a0 85125e8f7cdc99fd91dbd7280373c5bd8823e3156348f5bae6dacd436c919c6dd53e23487da03fd02396306d248cda0e9
9f33420f577ee8ce54b67080280d1ec69821bcb6a8839396f965ab6ff72a70
Каждый из этих блоков даёт MD5-хеш, равный 79054025255fb1a26e4bc422aef54eb4 .
Пункт второй – «имена файлов не должны повторяться, напрямую вытекает из третьего. Если в качестве имени файла на диске мы используем строку его md 5 хеша, то имена файлов не повторяются (реальные имена файлов (те, которые загрузил пользователь), мы можем хранить в базе данных). В случае загрузки пользователями двух одинаковых файлов, мы получаем у них одинаковые имена. И первое - файлы не будут дублированы, второе - мы не беспокоимся по поводу имен в директориях.
Теперь чуть более сложно, по поводу хранения файлов на диске. Я создаю структуру вложенных каталогов, опираясь на имена файлов. Здесь тоже полный простор для фантазии. Я ни в коем случае не призываю слепо копировать мой способ. Обычно я делаю два, три уровня вложенности каталогов. Первый уровень - это первые две буквы названия файла (не забыли, название файла это его md 5 хеш!);второй уровень это третья и четвертая буквы…
Каждый уровень вложенности дает мне * на 256 каталогов.
То есть, если в один каталог я могу загрузить не более 1000 файлов, то при одном уровне вложенности я могу безопасно разместить на диске 256 000 файлов; при двух уровнях вложенности – 65 536 000; при трех – 16 777 216 000 и так далее. Длинна строки md 5 хеша позволяет нам сделать 16 уровней вложенности в каталогах. На мой взгляд, этого хватит для обеспечения работы самых емких дисков. Хотя, исходя из практика, обычно, и трех уровней хватает «за глаза» для проектов любой сложности.
И напоследок. В тех же комментариях на хабре мне прозрачно намекнули, что я «лью воду из пустого в порожнее», так как данные вещи всем и хорошо известны. Что же возможно это и так. На «моем счету» около 20 крупных переписанных или дописанных проектов, и я нигде не встречал подобной системы хранения файлов. Максимум на что хватало фантазии разработчиков, это именовать каталоги по дате, а в внутри них уже файлы по порядковому номеру. Это было на сайте одного интернет издания… издание на протяжении пяти лет (до попадания ко мне в руки) каждый день публиковало статьи и соответственно через пять лет количество каталогов содержащих файлы выросло до полутора тысяч. То есть вплотную приблизилось к границе, за которой начинается «торможение» по файловой системе. Как правило программисты торопятся сдать проект, не задумываясь о тех объемах информации, которые будут находится на сайте через год два или десять лет.
Ситуации для хранения и обработки данных в браузере включают:
- сохранение состояния клиентского приложения, такого как текущий экран, введенные данные, пользовательские настройки и т. д.
- утилиты, которые обращаются к локальным данным или файлам и имеют строгие требования к конфиденциальности
- прогрессивные веб-приложения (PWA), которые работают в автономном режиме
Вот десять вариантов хранения данных браузера:
В этой статье рассматриваются эти десять различных способов хранения данных в браузере, рассматриваются их ограничения, плюсы и минусы, а также наилучшее использование каждого метода. Прежде чем мы перейдем к вариантам, сделаем небольшое примечание о сохранении данных.
Сохранение данных
Как правило, данные, которые сохраняются, будут:
- Постоянные (persistent): они остаются до тех пор, пока ваш код не решит удалить их, или
- изменяемые (volatile) : они остаются до завершения сеанса браузера, обычно, когда пользователь закрывает вкладку
Постоянные данные могут быть заблокированы или удалены пользователем, операционной системой, браузером или плагинами в любой момент. Браузер может принять решение об удалении более старых или больших элементов по мере приближения к граничной емкости, выделенной для этого типа хранилища.
Браузеры также записывают состояние страницы. Вы можете уйти с сайта и кликнуть назад или закрыть и снова открыть вкладку; страница должна выглядеть идентично. Переменные и данные, доступные только для сеанса, по-прежнему доступны.
1. Переменные JavaScript
- размер — нет строгих ограничений, но при заполнении памяти может произойти замедление работы браузера или сбои
- скорость чтения / записи — самый быстрый вариант
- сохранность — плохая: данные стираются при обновлении браузера
Сохранение состояния в переменных JavaScript — самый быстрый и простой вариант. Я уверен, что вам не нужен пример, но …
- легко использовать
- быстрота
- нет необходимости в сериализации или десериализации
- ненадежность: обновление или закрытие вкладки стирает все
- сторонние скрипты могут исследовать или перезаписывать глобальные значения (window). Вы уже используете переменные. Вы можете рассмотреть возможность сохранения состояния переменной при выгрузке страницы .
2. Хранилище узлов DOM
- размер — нет строгих ограничений, но не идеально для большого количества данных
- скорость чтения / записи — Быстрый
- сохранность — плохая: данные могут быть удалены другими скриптами или обновлением
Большинство элементов DOM на странице или в памяти могут хранить значения в именованных атрибутах. Безопаснее использовать имена атрибутов с префиксом data-:
- атрибут никогда не будет иметь связанных функций HTML
- Вы можете получить доступ к значениям с помощью свойства dataset или через методы .setAttribute() и .getAttribute().
Значения хранятся в виде строк, поэтому может потребоваться сериализация и десериализация. Например:
- вы можете определять значения в JavaScript или HTML, например <main data-value1=»1″>
- полезно для хранения состояния конкретного компонента
- DOM работает быстро! (вопреки распространенному мнению)
- ненадёжно: обновление или закрытие вкладки стирает значения
- только строки: требуется сериализация и десериализация
- большой DOM влияет на производительность
- сторонние скрипты могут исследовать или перезаписывать значения
Хранилище узлов DOM работает медленнее, чем переменные. Используйте его экономно в ситуациях, когда удобно хранить состояние компонента в HTML.
3. Web хранилище (localStorage и sessionStorage)
- размер — 5 МБ на домен
- скорость чтения / записи — синхронная работа: может быть медленной
- сохранность — данные остаются до тех пор, пока не будут удалены
Веб-хранилище предоставляет два похожих API для определения пар имя/значение. Используйте:
- window.localStorage для хранения постоянных данных и
- window.sessionStorage для сохранения данных только сеанса, пока вкладка браузера остается открытой
Храните или обновляйте именованные элементы с помощью .setItem():
Получайте их с помощью .getItem():
И удалите их с помощью .removeItem():
Другие свойства и методы включают:
- .length: количество хранимых элементов
- .key(N): имя N-го ключа
- .clear(): удаление всех сохраненных элементов
Изменение любого значения вызывает событие хранения в других вкладках / окнах браузера, подключенных к тому же домену. Ваше приложение может ответить соответствующим образом:
- простой API (пары имя / значение)
- параметры сеанса и постоянного хранилища
- хорошая поддержка браузера
- Только строки: требуется сериализация и десериализация
- неструктурированные данные без транзакций, индексации или поиска
- синхронный доступ повлияет на производительность больших наборов данных
Веб-хранилище идеально подходит для простых, небольших и разовых значений. Оно менее практично для хранения больших объемов структурированной информации, но вы можете избежать проблем с производительностью, записывая данные при выгрузке страницы.
4. IndexedDB
- размер — зависит от устройства. Не менее 1 ГБ, но может составлять до 60% оставшегося дискового пространства
- скорость чтения / записи — быстрый
- сохранность — данные остаются до тех пор, пока не будут удалены
IndexedDB предлагает низкоуровневый API, похожий на NoSQL, для хранения больших объемов данных. Хранилище можно индексировать, обновлять с помощью транзакций и выполнять поиск с помощью асинхронных методов.
IndexedDB API сложен и требует некоторого манипулирования событиями. Следующая функция открывает соединение с базой данных при передаче имени, номера версии и дополнительной функции обновления (вызываемой при изменении номера версии):
Следующий код подключается к базе данных myDB и инициализирует хранилище объектов todo (аналогично таблице SQL или MongoDB). Затем он определяет автоматически увеличивающийся ключ с именем id:
Как только соединение будет готово, вы можете с помощью .add добавить новые элементы данных в транзакцию:
И вы можете получить значения, например, первый элемент:
- гибкое хранилище данных с самым большим пространством
- надежные транзакции, возможности индексации и поиска
- хорошая поддержка браузера
- сложный обратный вызов и API на основе событий
- IndexedDB — лучший вариант для надежного хранения больших объемов данных, но вам может понадобиться библиотека-оболочка, такая как idb , Dexie.js или JsStore .
5. Cache API
- размер — зависит от устройства, но Safari ограничивает каждый домен до 50 МБ
- скорость чтения / записи — быстрый
- сохранность — данные остаются до очистки или через две недели в Safari
Аналогичная функция может получить элемент из кеша. В этом примере она возвращает основной текст ответа:
- хранит любой сетевой ответ
- может улучшить производительность веб-приложений
- позволяет веб-приложению работать в автономном режиме
- современный API
- не практично для хранения состояния приложения
- возможно менее полезно за пределами прогрессивных веб-приложений
Apple недоброжелательно относится к PWA и Cache API
Cache API — лучший вариант для хранения файлов и данных, полученных из сети. Вы, вероятно, могли бы использовать его для хранения состояния приложения, но он не предназначен для этой цели, и есть варианты получше.
5.5 AppCache
AppCache был предшественником Cache API . Это не то решение для хранения, которое вы ищете. Здесь ничего нет. Пожалуйста, двигайтесь дальше.
6. API доступа к файловой системе
- размер — зависит от оставшегося места на диске
- скорость чтения / записи — зависит от файловой системы
- сохранность — данные остаются до тех пор, пока не будут удалены
API доступа к файловой системе позволяет браузеру читать, записывать, изменять и удалять файлы из локальной файловой системы. Браузеры работают в изолированной среде, поэтому пользователь должен предоставить разрешение на определенный файл или каталог. Чтобы веб-приложение могло читать или записывать данные, как настольное приложение, используют FileSystemHandle.
Следующая функция сохраняет объект Blob в локальный файл:
- веб-приложения могут безопасно читать и записывать в локальную файловую систему
- меньше необходимости загружать файлы или обрабатывать данные на сервере
- отличная функция для прогрессивных веб-приложений
- минимальная поддержка браузера (только Chrome)
- API может измениться
Этот вариант хранения для меня очень интересен, но вам придется подождать пару лет, прежде чем он станет жизнеспособным для производственного использования.
7. API записей файлов и каталогов
- размер — зависит от оставшегося места на диске
- скорость чтения / записи — неизвестный
- сохранность — данные остаются до тех пор, пока не будут удалены
API записей файлов и каталогов предоставляют песочницы файловой системы доступной для домена, которые могут создавать, писать, читать и удалять каталоги и файлов.
- нестандартные, несовместимость между реализациями и поведение могут измениться.
MDN прямо заявляет: не используйте это на производственных сайтах . Поддержка будет в лучшем случае через несколько лет.
8. Файлы cookie
- размер — 80 КБ на домен (20 файлов cookie размером до 4 КБ в каждом)
- скорость чтения / записи — быстрый
- сохранность — хорошая: данные остаются до тех пор, пока они не будут удалены или не истечет время их жизни
document.cookie устанавливает значения cookie в клиентском JavaScript. Вы должны определить строку с именем и значением, разделенными символом равенства (=). Например:
Значения не должны содержать запятых, точек с запятой или пробелов, поэтому может потребоваться encodeURIComponent():
К дополнительным настройкам файлов cookie можно добавить разделители через точку с запятой, в том числе:
Пример: установить файл cookie, срок действия которого истекает через 10 минут и доступен по любому пути в текущем домене:
document.cookie возвращает строку, содержащую каждую пару имени и значения, разделенную точкой с запятой. Например:
Функция ниже анализирует строку и преобразует ее в объект, содержащий пары имя-значение. Например:
- надежный способ сохранить состояние между клиентом и сервером
- ограничен доменом
- автоматический контроль истечения срока действия с помощью max-age (секунд) или Expires (дата)
- используется в текущем сеансе по умолчанию (установите дату истечения срока, чтобы данные сохранялись после обновления страницы и закрытия вкладки)
Избегайте файлов cookie, используйте их если нет реальной альтернативы.
9. window.name
- размер — варьируется, но должно быть несколько мегабайт
- скорость чтения / записи — быстрый
- сохранность — данные сеанса остаются до закрытия вкладки
Свойство window.name устанавливает и получает имя контекста активного окна. Вы можете установить одно строковое значение, которое будет сохраняться между обновлениями браузера. Например:
Исследуйте значение, используя:
- легко использовать
- может использоваться только для данных сеанса
- Только строки: требуется сериализация и десериализация
- страницы в других доменах могут читать, изменять или удалять данные (никогда не используйте их для конфиденциальной информации)
Window.name не предназначен для хранения данных. Это хак, и есть варианты получше.
10. WebSQL
- размер — 5 МБ на домен
- скорость чтения / записи — медленная
- сохранность — данные остаются до тех пор, пока не будут удалены
WebSQL был попыткой перенести в браузер хранилище баз данных, подобное SQL. Пример кода:
Chrome и некоторые версии Safari поддерживают эту технологию, но против нее выступили Mozilla и Microsoft в пользу IndexedDB.
- разработан для надежного хранения и доступа к данным на стороне клиента
- знакомый синтаксис SQL, часто используемый серверными разработчиками
- ограниченная поддержка браузеров
- несогласованный синтаксис SQL в браузерах
- асинхронный, но медленный API на основе обратного вызова
- плохая работа
Не используйте WebSQL! Он не был жизнеспособным вариантом с тех пор, как устарела его спецификация в 2010 году.
Тщательная проверка хранилища
API хранилища может исследовать пространство , доступное для веб-хранилища, IndexedDB, и Cache API. Все браузеры, кроме Safari и IE, поддерживают это API, которое предлагает метод .estimate() для вычисления значений quota (пространства, доступного для домена) и usage (пространства, уже используемого). Например:
Доступны еще два асинхронных метода:
- .persist() : возвращает true если у сайта есть разрешение на хранение постоянных данных, и
- .persisted() : возвращает true если сайт уже сохранил постоянные данные
Панель «Приложение» в инструментах разработчика браузера ( в Firefox называется « Хранилище» ) позволяет просматривать, изменять и очищать localStorage, sessionStorage, IndexedDB, WebSQL, файлы cookie и кеш хранилища.
Заключение
Ни одно из этих решений для хранения не является идеальным, и вам нужно будет внедрить несколько решений в сложное веб-приложение. Это означает изучение дополнительных API. Но иметь выбор — это хорошо — конечно, при условии, что вы можете подобрать подходящий вариант!
Существует несколько технологий для хранения данных в браузере. Какая из них лучше?
Интернет-соединение может быть плохим или вовсе отсутствовать в определенных местах. Поэтому поддержка оффлайн-режима является одной из ключевых особенностей прогрессивных веб-приложений. Даже при наличии высокоскоростного подключения разумно применять кэширование и другие техники для улучшения пользовательского опыта. Существует несколько способов сохранения файлов (HTML, JavaScript, CSS, изображения и т.д.) и данных (пользовательские данные, новостные статьи и др.). Но какое решение лучше выбрать? И как обеспечить его долговечность?
Что использовать?
Могу посоветовать следующее:
- Для сетевых ресурсов, необходимых для работы приложения и отображения контента, используйте Cache Storage API (часть сервис-воркеров).
- Для других данных используйте IndexedDB (с оберткой из промисов).
Что насчет других механизмов?
В браузере также существуют другие механизмы хранения данных, но они имеют определенные ограничения и могут приводить к проблемам производительности.
Какой объем данных я могу хранить?
Как минимум, несколько сотен мегабайт, потенциально, сотни гигабайт. Это зависит от браузера, однако объем хранилища, как правило, зиждется на объеме доступной памяти в устройстве пользователя.
- Chrome позволяет использовать до 60% дискового пространства. Вы можете использовать StorageManager API для определения лимита (квоты).
- Internet Explorer 10 и более поздние версии может хранить до 250 Мб данных.
- Firefox позволяет хранить до 2 Гб данных. Вы можете использовать StorageManager API для определения лимита.
- Safari (как десктопный, так и мобильный) позволяет хранить до 1 Гб данных. При достижении лимита, Safari обращается к пользователю за разрешением увеличить квоту на 200 Мб.
Сегодня большая часть браузеров этого не делает, автоматически увеличивая объем хранилища в пределах квоты. Исключение составляет Safari, который при достижении 750 Мб запрашивает разрешение пользователя на увеличение лимита до 1,1 Гб. Попытка превысить квоту закончится провалом.
Как проверить остаток лимита?
Для этого во многих браузерах можно воспользоваться StorageManager API. Он показывает общее количество байт, использованных IndexedDB и Cache API, позволяя рассчитать остаток.
Необходимо учитывать, что StorageManager API пока поддерживается не всеми браузерами. Однако даже если он поддерживается, необходимо предусматривать обработчик ошибок. В некоторых случаях квота может превышать реальный объем хранилища.
Инспектирование
При разработке вы можете использовать инструменты браузера для отслеживания состояния различных хранилищ и их очистки.
Во время работы над статьей я написал этот простой инструмент для быстрого тестирования возможностей хранилищ. Это быстрый и легкий способ поэкспериментировать с разными механизмами хранения данных и посмотреть, что произойдет при превышении квоты.
Как обрабатывать ошибки?
Что делать при достижении лимита? Разумеется, обрабатывать ошибки, будь то QuotaExceededError или нечто иное. Затем, в зависимости от дизайна вашего приложения, следует выбрать способ их обработки. Можно, например, удалять старый контент или данные в зависимости от их размера, либо предоставлять пользователю возможность решать, что удалять.
IndexedDB и Cache API выбрасывают DOMError QuotaExceededError при превышении квоты.
IndexedDB
При достижении лимита попытка записать данные в IndexedDB потерпит неудачу. Будет вызван метод onabort() с событием в качестве аргумента. Событие будет содержать DOMException в свойстве ошибки. Проверка имени ошибки вернет QuotaExceededError.
Cache API
Попытка записать данные в Cache API при достижении лимита будет отклонена с QuotaExceededError DOMException.
Как работает очистка хранилища?
Веб-хранилища подразделяются на две категории, «автономные» и «управляемые». Автономное означает, что хранилище может быть очищено браузером без участия пользователя, однако оно менее устройчиво при длительном использовании, а также при наличии критических данных. Управляемые хранилища не очищаются автоматически при заполнении. Пользователь должен вручную очищать такие хранилища (через настройки браузера).
По умолчанию, веб хранилища (IndexedDB, Cache API и др.) относятся к категории автономных, что означает, что если не установлено ручное управление, браузер может самостоятельно очищать хранилище при наличии определенных условий, например, при заполнении.
Условия для очистки хранилища следующие:
- Chrome при заполнении хранилища удаляет данные, начиная с наименее востребованных (самых старых по времени использования), до тех пор, пока не решится проблема переполнения.
- IE 10+ не очищает хранилище, но блокирует возможность записи данных.
- Firefox поступает аналогично Chrome.
- Safari раньше не очищал хранилище, но недавно в него был добавлен семидневный срок хранения данных.
Бонус: обертка из промисов над IndexedDB
IndexedDB — это низкоуровневое API, предполагающее определенную настройку перед использованием, которая может быть лишней при необходимости хранения простых данных. В отличие от большинства современных API, основанных на промисах, она основано на событиях. Обертка из промисов, такая как idb, скрывает некоторые мощные возможности данного хранилища, но, что более важно, она также скрывает его сложные внутренние механизмы (транзакции, версионирование).
Заключение
Времена ограниченных хранилищ и запросов разрешения пользователя на увеличение лимита канули в лету. Сайты могут эффективно хранить все ресурсы и данные, необходимые им для работы. С помощью StorageManager API вы можете определить, сколько памяти использовано и сколько еще осталось. А с помощью перевода хранилища в режим ручного управления, вы можете защитить данные от удаления.
От автора: знаете ли вы, какой вариант хранилища в браузере рассмотреть в 2021 году? Современные веб-браузеры предлагают несколько вариантов хранения веб-приложений. И каждый вариант хранения уникален и имеет свои свойства и применение.
Однако для выбора подходящего варианта для вашего случая использования требуется твердое понимание их свойств и ограничений. В этой статье я расскажу о пяти вариантах хранения в браузере и их состоянии, помогая вам найти наиболее подходящий вариант для вашего использования.
Введение в параметры и свойства хранилища
Если вы бегло ознакомитесь с Chrome DevTools, вы сможете найти типы хранилищ браузера, перечисленные ниже:
JavaScript. Быстрый старт
Изучите основы JavaScript на практическом примере по созданию веб-приложения
Давайте узнаем подробности о каждом варианте хранения и его уникальных свойствах.
Локальное хранилище
Локальное хранилище является наиболее широко используемым хранилищем из-за его простоты. Оно позволяет хранить пары ключ-значение, сериализованные в виде строк. Вы можете выполнять следующие действия в локальном хранилище:
Чтобы установить значения в локальном хранилище в виде массивов, объектов и т.д., Необходимо преобразовать значения в строки с помощью JSON.stringify. При получении JSON.parse восстанавливает элемент обратно в JSON.
var sessionItem = JSON . parse ( localStorage . getItem ( 'session' ) ) ;Локальное хранилище совместно используется всеми вкладками и окнами из одного источника.
Срок действия данных не истекает.
Поддержка событий хранилища.
Давайте подробнее рассмотрим события хранилища.
Предел хранилища составляет 5 Мб в ведущих браузерах (можно безопасно планировать этот предел).
Сессионное хранилище
Хранилище сеансов похоже на локальное хранилище, с той лишь разницей, что данные в хранилище сеанса хранятся до тех пор, пока вы не закроете вкладку браузера.
Таким образом, хранилище сеансов привязано к источнику приложения, а также к вкладке браузера.
Мне было любопытно узнать, как события хранилища работают с хранилищем сеансов. Даже при наличии событий хранилища изоляция вкладок браузера все еще существует.
Следовательно, в сессионном хранилище событие хранения доступно только в iFrames на одной вкладке. Кроме того, как в локальное хранилище, так и в хранилище сеансов, доступ является синхронным, и ваш код JavaScript будет ждать, пока он получит данные при доступе к этим хранилищам.
IndexedDB
IndexedDB ближе к обычной базе данных NoSQL по сравнению с рассмотренными нами хранилищами. Вы можете использовать IndexedDb, если имеете дело со сложными объектами JavaScript, которые трудно сериализовать.
IndexedDB также поддерживает транзакции и хорошо работает с веб-воркерами.
Например, Twitter использует IndexedDB с тремя таблицами для сохранения данных. Вы можете найти последние поисковые запросы в массиве для повышения удобства использования.
Может хранить любые данные типа JavaScript, такие как объект (большой двоичный объект, файл) или массив и т.д., В виде пар ключ-значение.
JavaScript. Быстрый старт
Изучите основы JavaScript на практическом примере по созданию веб-приложения
API-интерфейсы IndexedDB асинхронны, поэтому по завершении запроса он возвращает обратный вызов.
Может хранить структурированные данные, такие как данные календаря.
Web SQL (устарело)
Недавно W3C объявил, что спецификации WebSQL устарели. В качестве альтернативы W3C предлагает использовать более эффективную indexedDB вместо использования веб-SQL.
В Web SQL есть три метода:
var db = openDatabase ( 'testDB' , '1.0' , 'Test DB' , 3 * 1024 * 1024 ) ; tr . executeSql ( 'CREATE TABLE IF NOT EXISTS TestTable (id unique, data)' ) ; tr . executeSql ( 'INSERT INTO TestTable (id, data) VALUES (1, "itemOne")' ) ; tr . executeSql ( 'INSERT INTO TestTable (id, data) VALUES (2, "itemTwo")' ) ;В отличие от других вариантов хранения, вы можете использовать SQL-запросы для взаимодействия с базой данных.
Для любого, кто знаком с SQLite, кривая обучения минимальна или отсутствует.
Файлы cookie
Давайте посмотрим, как мы можем получить доступ к клиентскому cookie.
document . cookie = "username=Charuka Herath; expires=Thu, 31 Dec 2020 12:00:00 UTC; path=/" ; document . cookie = "username=; expires=Thu, 31 Dec 2019 12:00:00 UTC; path=/" ;Однако важно отметить, что файлы cookie отправляются из браузера обратно на сервер для каждого запроса. Поэтому делайте их как можно меньше, чтобы снизить накладные расходы.
Эффективно при получении сеансов, сведений о страницах, потоков веб-страниц.
Файлы cookie сохраняются. Таким образом, данные можно сохранять в браузере до тех пор, пока они не будут очищены.
Может управлять персонализированным контентом и обслуживать его в соответствии с предпочтениями конкретного пользователя.
Поддерживает перекрестное происхождение с подстановочными знаками.
Заключение
Таблица сравнения типов хранилищ
С точки зрения безопасности эти варианты хранения не предназначены для хранения конфиденциальных данных. Но растет тенденция к хранению токенов аутентификации (токенов OpenID) в локальном хранилище, поддерживаемом популярными библиотеками JavaScript, которые открыты для интерпретации. Однако для Cookie есть исключение в хранении идентификатора сеанса, который специально разработан для его хранения.
При выборе вариантов хранения, если требуется только хранить простые пары ключ-значение, лучшим вариантом будет локальное хранилище. Если вы планируете немного улучшить безопасность вкладок браузера, вы можете использовать Session Storage. И помните об ограничениях хранилища, прежде чем выбирать эти два варианта.
И для любых расширенных требований к хранилищу вы можете использовать IndexedDB, который лучше всего подходит в качестве решения для базы данных. Кроме того, для фоновой обработки с веб-воркерами это идеальное решение, позволяющее управлять транзакциями.
Надеюсь, статья будет полезна для расширения кругозора по хранению данных в браузере. Спасибо за прочтение!
Автор: Charuka E Bandara
Редакция: Команда webformyself.
JavaScript. Быстрый старт
Изучите основы JavaScript на практическом примере по созданию веб-приложения
Читайте также: