• Техногрет
  • Кеширование невозможного

    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.