----[ Browser Storage ... under0x77ater ] ----[ NITRO ... ] "Стою на шестом этаже пятиэтажного дома, да это незаконно, но здесь многим так знакомо" Cookies впервые появились в Netscape, чтобы не хранить данные на веб сервере. Технология прижилась и даже с ростом вместимости жестких дисков до сих пор широко применяется. С появлением ajaxа и вследствие многократного увеличения запросов, приходится каждый раз при посылке запроса посылать также и cookies, что ведет к росту трафика, да и ограничение на них всего три килобайта. Первым эту проблему попытались исправить в Microsoft, внедрив поддержку userData в свой браузер пятой версии, но только после публикации предварительного описания HTML5 технология стала освещаться в различных веб изданиях. В статье расскажется об использовании данных в браузере на примерах Internet Explorer и Mozilla Firefox. ----[ WHAT THE FUCK ?! ... ] Из преимуществ можно отметить такие факты, как : уменьшение трафика, неограниченная длина данных, да и просто гарантия что у вас будет не как у всех xD. Применений такому способу масса - сохранение черновиков в веб формах, автозаполненных данных, хранение неособо важных данных, как дата последнего посещения, поисковый запрос или, например, название темы оформления сайта. Из достоинств метода можно выделить еще и безопасность - злоумышленник будет весьма удивлен отсутствию кук на сниффере. Но это вопрос времени. Так почему бы и не воспользоваться таким мощным и удобным средством?
----[ USER DATA ... ] userData появился в пятой версии Microsoft Internet Explorer и использовался для запоминания расположения элементов. Все данные представлены в виде связанной xml структуры в файле с расположением в Application Data/Microsoft/Internet Explorer/UserData. Первым технологию заметили программисты из Google. Чуть позже userData стали использовать как механизм хранения данных между сессиями. Все хранимые методы и свойства становятся доступными после события window.onload. Для начала работы с userData следует прописать определенную конструкцию в стиль документа. ie\:userdata {behavior:url(#default#userData);} После этого можно приступать к работе с данными, используя методы объекта. | Свойства | | expires | Устанавливает или возвращает дату устаревания информации в хранилище | | XMLDocument | Возвращает ссылку на объект XMLDocument, предоставляемый объектом | | Методы | | load ( | параметр object userDat Элемент, которому назначено поведение userData | параметр string sStoreName Имя хранилища данных | результат nothing ) | | Метод load осуществляет чтение информации из хранилища данных. | Для правильного выполнения метода load, элемент должен содержать установленный атрибут ID. | <html xmlns:IE> | <head> | <meta http-equiv="Content-Type" content="text/html; charset=windows-1251"> | <style type='text/css'> | ie\:userdata {behavior:url(#default#userData);} | </style> | </head> | | <body onload='oUserData.load("sDataStor");'> | <ie:userData ID="oUserData" /> | </body> | </html> | | save ( | параметр object userDat Элемент, которому назначено поведение userData | параметр string sStoreName Имя хранилища данных | результат nothing ) | | Метод save осуществляет запись информации в хранилище данных. Доступность хранилища зависит от адреса ресурса, использующего | это хранилище. Для того, что бы ресурс мог обратится к хранилищу данных, адрес ресурса, загружающего информацию из указанного | хранилища данных, должен совпадать с адресом ресурса, создавшего это хранилище с точностью до всех используемых папок. | <html xmlns:IE> | <head> | <meta http-equiv="Content-Type" content="text/html; charset=windows-1251"> | <style type='text/css'> | ie\:userdata {behavior:url(#default#userData);} | </style> | </head> | | <body onunload='oUserData.save("sDataStor");'> | <ie:userData ID="oUserData" /> | </body> | </html> | | setAttribute ( | параметр string sAttrName Имя ключа | параметр string vAttrValue Назначаемое ключу значение | результат nothing ) | | Метод setAttribute устанавливает значение нужному ключу, и в случае его отсутсвия сама добавляет ключ. | | getAttribute ( | параметр string sAttrName Имя ключа | результат nothing ) | | Метод getAttribute возвращает значение ключа или пустую строку. | | removeAttribute ( | параметр string sAttrName Имя ключа | результат nothing ) | | Метод getAttribute возвращает значение ключа или пустую строку. | | | <HEAD> | | <STYLE> | .userData {behavior:url(#default#userdata);} | </STYLE> | | <SCRIPT> | function fnGet(){ | oPersistInput.load("oDataStore"); | oPersistInput.value=oPersistInput.getAttribute("sPersistAttr"); | } | function fnSet(){ | oPersistInput.setAttribute("sPersistAttr",oPersistInput.value); | oPersistInput.save("oDataStore"); | } | function fnRem(){ | oPersistInput.removeAttribute("sPersistAttr"); | oPersistInput.save("oDataStore"); | } | </SCRIPT> | </HEAD> | | <BODY> | <INPUT type=text class=userData id=oPersistInput> | <INPUT type=button value="Get Attribute" onclick="fnGet()"> | <INPUT type=button value="Set Attribute" onclick="fnSet()"> | <INPUT type=button value="Remove Attribute" onclick="fnRem()"> | </BODY> | ----[ WINDOW.NAME ... ] DOM свойство я решил затронуть не просто так. Первым этот метод хранения данных предложил использовать Thomas Frank, в силу сохранения свойства на протяжении всей сессии жизни окна / закладки и является необязательным. Для удобства хранения данных я решил использовать структуру ключ1=значение1&ключ2=значение2...ключn=значениеn. Мой маленький набор функций позволяет заменять значения данных, добавлять новые и удалять существующие. | function replaceKey(key, value) { | if(window.name == '' || window.name.indexOf(key) == -1){ | alert('No data in storage saved') | return; | } | delKey(key); | addKey(key,value); | } | | function addKey(key, value) { | myStorage = window.name; | if(myStorage.indexOf(key+'=')!= -1) { | alert('Yet another key'); | return; | } | myStorage += key + '=' + encodeURIComponent(value) +'&'; | window.name = myStorage; | } | | function getKey(key){ | if(window.name == '' || window.name.indexOf(key) == -1){ | alert('No data in storage saved') | return; | } | myStorage = window.name; | temp = myStorage.substring(myStorage.indexOf(key)+key.length,myStorage.length); | temp = temp.substring(1,temp.indexOf('&')); | return temp; | } | | function delKey(key){ | if(window.name == '' || window.name.indexOf(key) == -1){ | alert('No data in storage saved') | return; | } | value = getKey(key); | myStorage = window.name; | rExp = key + '=' + value + '&'; | window.name = myStorage.replace(rExp, ''); | } | | replaceKey ( | параметр string key Имя ключа | параметр string value Значение | результат nothing ) | | Фунцкция replaceKey удаляет меняет значение ключа на новое. | | addKey ( | параметр string key Имя ключа | результат nothing ) | | Функция addKey добавляет значение к уже сущестующим. | | delKey ( | параметр string key Имя ключа | результат nothing ) | | Функция delKey удаляет ключ из массива данных. | | getKey ( | параметр string key Имя ключа | результат string temp Значение ) | | Функция getKey возвращает значение ключа. | | <html> | <head> | <title>Пример к статье</title> | <script type="text/javascript" src="ex.js"></script> | </head> | | <body> | Hello world | <script type="text/javascript"> | addKey('key1','value1'); | // window name = key1=value1& | addKey('key2','value2'); | // window name = key1=value1&key2=value2& | delKey('key2'); | // window name = key1=value1& | replaceKey('key1','newvalue'); | // window name = key1=newvalue& | </script> | </body> | </html> ----[ STORAGE ... ] Описание модели, реализующей хранение данных на стороне клиента, появилось в html 5 (http://www.whatwg.org/specs/web-apps/current-work/#storage0). Данный способ является на данный момент самым удобным и даже кроссбраузерным.Люди в w3c представляют структуру storage так Mozilla Firefox предлагает использовать два типа хранилищей - sessionStorage и globalStorage. Первый доступен только на протяжение времени жизни страницы и как только страница закрывается получить доступ к данным уже невозможно. Получить состояние storage можно через dom свойство Dom.storage.enabled | // Сохраняем в sessionStorage переменную username со значением antichat | sessionStorage.username = "antichat"; | // Проверяем, сохранилась ли переменная | alert( "username = " + sessionStorage.username ); | // Получаем дескриптор текстового поля | var field = document.getElementById("field"); | | // Если включен режим автосохранения, загружаем черновик | if ( sessionStorage.autosave ) { | field.value = sessionStorage.autosave; | } | | // Проверяем каждую секунду содержимое текстового поля на изменения | setInterval(function(){ | // Сохраняем в черновик | sessionStorage.autosave = field.value; | }, 1000); GlobalStorage позволяет держать данные на протяжение длительного промежутка времени. | // Сохранить переменную snippet в globalStorage только для сайта antichat.ru | globalStorage['antichat.ru'].snippet = "underWHAT?!"; Счетчик посещения | // parseInt используется для перевода переменной visits в число | // все данные в *Storage хранятся в виде строки | globalStorage['mozilla.org'].visits = | parseInt( globalStorage['mozilla.org'].visits || 0 ) + 1; Пример #1 http://aaronboodman.com/halfnote/ Пример #2 http://channy.creation.net/work/firefox/domstorage/# Thomas Frank написал библиотеку sessvars, облегчающей работу с globalStorage ( http://www.thomasfrank.se/sessvars.js ) Единственная переменная-свойство объекта sessvars, которую вы не должны трогать, это $, потому что она содержит ряд полезных методов: Методы | sessvars.$.clearMem() | Очищает sessvars | | sessvars.$.usedMem() | Возвращает объем используемой памяти в килобайтах | | sessvars.$.usedMemPercent() | Возвращает объем используемой памяти в процентах от общего возможного объема | | sessvars.$.debug() | Выводит окно дебага вверху страницы (как в примере выше) | | sessvars.$.flush() | Явно сохраняет текущее состояние sessvars, так что все данные будут сохранены когда будет совершен переход на другую страницу. Это редко бывает необходимо, так как в нормальной ситуации это делается автоматически при событии unload. Флаги Также есть ряд различных флагов, которыми вы можете устанавливать поведение sessvars: | sessvars.$.prefs.memlimit | По умолчанию - 2000 | Указывает объем данных в Кб, разрешенный для хранения в sessvars. По умолчанию 2000 Кб, так как Opera 9.25 имеет ограничение чуть выше этого числа. У остальных браузеров (IE7.0, Firefox 1.5/2.0 и Safari 3.0) ограничение намного выше - 10 Мб не представляют сложности для этих браузеров. | sessvars.$.prefs.autoFlush | true/false, по умолчанию true | Определяет, будет ли метод flush() вызываться автоматически | sessvars.$.prefs.crossDomain | true/false, по умолчанию false | Если флаг установлен в true, содержимое sessvars можно читать из разных доменов (если оба сайта используют sessvars.js). | sessvars.$.prefs.includeFunctions | true/false, по умолчанию false | Определяет, будет ли sessvars сохранять функции. | sessvars.$.prefs.includeProtos | true/false, по умолчанию false | Если true, то будут сохранены свойства, назначенные прототипам различных данных или объектов. Редко бывает необходимо. ----[ PersistJS ... ] PersistJS - первая javascript библиотека, которую можно поправу назвать кроссбраузерной ( http://pablotron.org/?cid=1557 ) В данный момент он поддерживает следующие механизмы: | Flash 8 | Google Gears | localstorage | whatwg_db | globalstorage | UserData (Internet Explorer) | cookie: хранение данных при помощи Cookie. Cookies используются только в случае отсутствия остальных способов. Сохранение данных | // создаем новое хранилище данных | var store = new Persist.Store('My Data Store'); | | // данные для хранения | var data = "Некая длинная строка ..........."; | | // сохраняем данные | store.set('saved_data', data); Получение данных | // получаем данные и показываем их пользователю | store.get('saved_data', function(ok, val) { | if (ok) | alert('saved data = ' + val); | }); Удаление данных | store.remove('saved_data'); Пример #1 http://jstoolbox.com/demo/persistjs/test/test_flash.html ----[ OUTRO ... ] При написании статьи были использованы материалы с сайта habrahabr.ru, jstoolbox.com, developer.mozilla.org и msdn.microsoft.com. Надеюсь, что информация не пройдет мимо, потому что эта статья как Ктулху - всё равно рано или поздно придёт и захавает. 2008
На хабре тож рассматривался вопрос хранения данных не в кукисах а в window.name, а на PHPconf 2008 у Ильи Канторова был доклад о хранение даных на стороне клиента в Browser Persistence (хранение данных в DOM), но пока это еще не поддерживаю современные браузеры... Надо будет почитать и разобраться в этой технологии, и использовать уже ее
почитал по диагонали, storage показался наиболее простым для понимания. кто что думает по поводу userData, Storage и window.name? (последний имхо самый неудобный - надо парсить) кто использовал эти методы и какова у них кроссбраузерность?
у меня трабл с sessvars.js, в оепре и осле данных сехраняются, а в мазиле *уй, не подскажете как мона исправить, переделывать не хотелось бы, имхо весь сайт уже сделан, только мазила подвела...