Pull to refresh

«Виртуальное хранилище» на стороне клиента с jQuery

Reading time3 min
Views6.5K
В некоторых случаях абсолютно бессмысленно и неоправданно нагружать как клиентскую часть веб-приложения, так и серверную. Чтобы не ходить долго вокруг да около, приведу пример из жизни. От разработчика мне достался один интернет-магазин, в котором работа с корзиной происходила следующим образом. При клике на кнопку добавления товара в cookie сохранялись ID товара и его количество. Соответственно, чтобы при посещении различных страниц пользователю показывалось, что находится в корзине, в каком количестве, сколько это добро стоит и прочие данные, серверному приложению приходилось выполнять следующие функции:
  1. получение списка ID товаров из cookie;
  2. запрос в БД, из которой возвращалось название товара, его стоимость и прочие необходимые данные;
  3. использование шаблонизатора (Smarty) для генерирование блока корзины на ряду с генерацией остального содержимого.

Все вроде бы и ничего. Я думаю, многие с подобными схемами сталкивались и не раз. Но передо мной стояла задача оптимизации приложения, и я решил убрать среди прочего лишнюю нагрузку с сервера путем устранения как запросов в БД, так и генерацией блока корзины. Хотелось бы хранить все данные о выбранных товарах на стороне клиента. Причем, в идеале хотелось хранить не только массив выбранных товаров, но и уже готовый HTML-код блока корзины, кроме того, таблицу с товарами для страницы оформления заказа. Но как это сделать?

Ждать кроссбраузерной поддержки JavaScript с клиентским хранилищем можно еще очень долго. А использовать cookie для этой задачи нецелесообразно, как минимум потому, что длина строки в cookie весьма ограничена. Я предлагаю следующее решение в виде плагина для jQuery и небольшого дополнения к серверной части.

JavaScript


;(function($){
	var self={
		config:		{
			//Вызов функции после того, как все объекты будут считаны из хранилища
			callback:	function(){},
			//Путь к серверному хранилищу
			path:		'storage.php'
		},
		current:	{
			//Вызвано впервые?
			first:		true
		},
		//Само хранилище данных
		storage:	{},
		init:		function(objects,config){
			if(!self.current.first)return;
			self.current.first=false;
			//Уст. конфиг
			$.extend(self.config,config);
			//Обраб. объекты
			self.storage=objects;
			//Восст. объекты
			self.get();
			$(window).unload(self.set);
			$('iframe').unload(self.set);
		},
		//Расширяет объекты
		ext:		function(objects){
			for(var k in objects){
				if(typeof(self.storage[k])=='undefined'){
					self.storage[k]={};
				};
				//Расширяем
				if(typeof(objects[k])=='object'){
					$.extend(true,self.storage[k],objects[k]);
				} else {
					self.storage[k]=objects[k];
				};
			};
		},
		//Возвращает объекты из хранилища
		get:		function(){
			$.getJSON(self.config.path,function(data){
				self.ext(data);
				self.config.callback();
			});
		},
		//Сохраняет в хранилище
		set:		function(){
			$.ajax({
				type:	'POST',
				url:	self.config.path,
				data:	{
					storage:	JSON.stringify(self.storage)
				}
			});
		}
	};
	$.extend({
		storage:	self.init,
		storageUpdate:	self.set
	});
})(jQuery);


PHP: storage.php


<?
session_start();
if(isset($_POST['storage'])){
	$_SESSION['storage']=$_POST['storage'];
}
elseif(isset($_SESSION['storage'])){
	echo $_SESSION['storage'];
}
?>


Таким образом, мы имеем виртуальное хранилище любых данных на стороне клиента с косвенным использованием сервера. Как это можно применить на практике?

var a={i:0};
$(function(){
	$.storage({storageA:a},{
		callback:	function(){
			a.i++;
			alert('Вы загрузили страницу в '+a.i+'-й раз.');
		}
	});
});


То есть для разработчика приложения схема хранения данных абсолютно прозрачна, и ему не стоит беспокоиться о том, в каком виде и как хранить данные. В данном случае все данные объекта a перед переходом на другую страницу будут сохранены в нашем хранилище. И сразу же после открытия другой страницы данные будут занесены в объект a.

P. S. Многие могу воскликнуть, мол, зачем такая сложность, если можно оптимизировать серверную часть приложения, хранить данные сразу в сессии и отдавать тот же самый объект клиенту сразу при генерации страницы (тут вариантов масса). У меня есть ответ. Давайте представим, что мы пошли по пути оптимизации приложения, где почти все динамические страницы хранятся во временном серверном кэше в статическом HTML-виде. Кстати, если необходимо таким образом хранить более важные данные, эту схему можно «подсолить» хэш-защитой с помощью cookie.
Tags:
Hubs:
+3
Comments24

Articles