Кеширование невозможного

HTML и CSSXSLTJavaScriptИзображенияСофтEtc
Сергей Золотухин

22 ноября 2005


Давно уже никто не спорит о том, что кеширование выручает как пользователей, так и разработчиков даже на среднем по посещаемости сайте. Но иногда обстоятельства складываются таким образом, что обычным кешированием не обойтись.

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

Как поступать в этих случаях? Можно обновлять кеш каждую минуту. Или хранить две версии кеша: для авторизованных и неавторизованных пользователей. В каждой конкретной ситуации с проблемой можно справиться по-разному, однако есть как минимум одно общее решение.

Самое простое: сначала получить HTML с общим для всех вариантов кеша содержимым, а затем «доработать» его с помощью, например, JavaScript. Ниже показан способ отображения текущего времени, на примере которого можно продемонстрировать основные моменты, характерные для подобных решений:

01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
<div id="divCurrentTime" style="display:none"></div>
<script type="text/javascript">
    MakeupCurrentTime()
    function MakeupCurrentTime()
    {
        var elem = document.getElementById('divCurrentTime')
        if( elem )
        {
            var d = new Date()
            elem.appendChild( document.createTextNode(d.toString()) )
            elem.style.display = 'block'
        }
    }
</script>

Момент первый, важный: не смотря на то, что разные пользователи в разное время видят разный контент, HTML выдается один, т. е. происходит кеширование — именно то, к чему мы стремились.

Момент второй, не менее важный: нужно предусмотреть ситуацию, когда скрипты на стороне пользователя по каким-либо причинам не выполняются. Изначально элемент div в строке 01 (divCurrentTime) скрыт, видимым его делает именно скрипт. Если скрипт не выполнится, элемент divCurrentTime останется скрытым и пользователь ничего не увидит.

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

01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
<div id="divLoginForm"></div>
<div id="divUserGreetings" style="display:none"></div>
<script type="text/javascript">
    MakeupAuthView()
    function MakeupAuthView()
    {
        var greetingsStr = GetUserGreetingsStr()
        if( greetingsStr )
        {
            document.getElementById('divLoginForm').style.display = 'none'
            var elem = document.getElementById('divUserGreetings')
            elem.appendChild( document.createTextNode(greetingsStr) )
            elem.style.display = 'block'
        }
    }
</script>

Все это похоже на пример с текущим временем, но ситуация отличается тем, что есть состояние «по умолчанию»: в случае возникновения каких-либо проблем со скриптом пользователю показывается форма для входа в систему — это гораздо лучше, чем ничего.

То есть, если скрипт не сработал или пользователь не авторизован (функция GetUserGreetingsStr() вернула null), форма для входа в систему отображается. Если же со скриптом все в порядке и пользователь авторизован (функция GetUserGreetingsStr() вернула не null и не пустую строку), отображается текст приветствия.

Осталось разобрать работу функции GetUserGreetingsStr(). Ничего сложного в ней нет: она получает данные от сервера, подгружая, к примеру, внешний XML.