Когда вокруг так много новых технологий, непросто понять, на изучение какой стоит потратить время.
(Karl Seguin)

Сейчас наступило интересное время, когда одни новые технологии стремительно меняются другими новыми, которые тоже быстро меняются. Положительная производная этого процесса в том, что, пока крутится этот технологический калейдоскоп, работа для девелопера найдётся. Но, иногда возникают задачи, для решения которых, говоря образным языком, лучше подойдёт не новая бензопила, а пилочка в старом перочинном ножике.

Изображение - Сайт на основе одной HTML-страницы

В статье показан приём разработки сайта, когда основной результат достигается за счёт использования базовых механизмов открытых стандартов.

Архитектура: Frontend, статический HTTP-сервер, XmlHttpRequest (XHR), REST.

IDE: Notepad, Notepad++ (Windows), Gedit (Linux).

Совместимость: браузер должен поддерживать JavaScript и HTML DOM.

Суть приёма


Сайт разрабатывается на основе HTML-страницы, через которую организован доступ к файлам контента. HTML-страниц, по замыслу разработчика, может быть сколько угодно, но, для достижения полной функциональности, и одной будет достаточно. В HTML-странице, ссылки на файлы контента, описываются в виде обычных HTML-ссылок, по правилам REST. За счёт расположения ссылок в одном месте, достигается ссылочная целостность.

Контент располагается в текстовых файлах и представляет собой текст, отформатированный типовой HTML-разметкой. Ограничений на расположение файлов контента нет, но будет логично, если их разместить в тематических разделах (директориях). Файлы контента не имеют связи с HTML-страницей и могут быть показаны на одной или нескольких HTML-страницах.

Сперва подгружается HTML-страница. Затем определяется и подгружается файл контента. Имя файла контента прописано в URL HTML-ссылки и определяется по правилам REST. Подгрузка файла контента осуществляется через XHR.

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

Всё это немного напоминает SSI, только на Frontend-е.

Как это работает


Считать URL HTML-ссылки и определить параметры:
function getUrlParametr(parName) {
  var params = location.search.substring(1).split("&");
  for (var i = 0; i < params.length; i++) {
      if (params[i].split("=")[0] == parName) {
          return params[i].split("=")[1];
      }
  }
  return "";
}

Количество и наименование параметров определяет разработчик, главное, чтобы в HTML-cтранице, был предусмотрен функционал по их обработке.

Загрузить и отобразить контент:
function loadXMLDoc(divName, contentFile) {
  var xmlhttp=new XMLHttpRequest();
  xmlhttp.onreadystatechange = function()
  {
    if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
    {
      document.getElementById(divName).innerHTML = xmlhttp.responseText; // отобразить контент
    }
  }
  xmlhttp.open("GET",contentFile,true);
  xmlhttp.send();
}

В параметре «id» задано расположение файла контента, которое определяется после загрузки HTML-cтраницы:
function onPageLoad() {
  var paramId = getUrlParametr("id");
  if(paramId == "")   paramId = "/xdata/news.htm"; // дефолтный контент
  loadXMLDoc("div_body",paramId);
}

<body onload='onPageLoad()'>

HTML-ссылка составлена так, что HTML-страница ссылается на саму себя, но с разными значениями параметра «id»:
<a href='site-1-page.htm?id=/it/it-box.txt'>ИТ копилка</a>

Для добавления нового контента, надо просто создать файл контента и добавить HTML-ссылку. Расширение файла контента может быть любым, но будет удобнее, если оно будет соответствовать известному MIME-типу, например «txt» или «htm». Так будет проще перенести сайт на внешний ресурс.

Это ключевые аспекты для создания информационного сайта. Интерактивность, при необходимости, может быть добавлена на основе веб-сервисов. Если же используется больше одной HTML-страницы, то можно, например, разработать одно меню для всех страниц, которое будет загружаться по тому же принципу, что и контент. Это облегчит поддержание ссылочной целостности, но расплатой будет лишний XHR запрос.

Как вместо файла контента вставить HTML-страницу


Чтобы в базовую HTML-страницу вставить другую HTML-страницу, проще всего использовать HTML-тег iframe. В этом случае XHR не нужен. В URL надо добавить ещё один параметр, например «iframe», и обрабатывать его при загрузке базовой HTML-страницы:
function onPageLoad() {
  var paramId = getUrlParametr("id");
  var paramIframe = getUrlParametr("iframe");
  if(paramId == "")   paramId = "/it/it-box.txt"; // дефолтный контент
  if(paramIframe == "" || paramIframe == "0") loadXMLDoc("div_body",paramId);
  if(paramIframe == "1") document.getElementById("div_body").innerHTML = "<iframe src='" + paramId + "'></iframe>";
}

Ключевое отличие состоит в том, что файл контента встроится в DOM базовой HTML-страницы и будет обработан единым CSS, а HTML-страница, подгруженная в iframe, нет.

Когда HTML-страница расположена не в корне


Бывает нужно разработать не весь сайт, а, например, тематический раздел. Чтобы HTML-ссылки оставались актуальными, надо учитывать путь к разделу:
  function onPageLoad(rootPath) {
    var paramId = getUrlParametr("id");
    var paramIframe = getUrlParametr("iframe");

    if(paramIframe == "" || paramIframe == 0) {
      if(paramId == "")   paramId = rootPath + "/it/it-box.txt"
      else paramId = rootPath + paramId;
      loadXMLDoc("div_body",paramId);
    }

    if(paramIframe == 1) {
      paramId = rootPath + paramId;
      document.getElementById("div_body").innerHTML = "<iframe src='" + paramId + "' width='100%' height='400'></iframe>";
    }

    if(paramIframe == 2) {
      document.getElementById("div_body").innerHTML = "<iframe src='" + paramId + "' width='100%' height='400'></iframe>";
    }
  }
}

<body onload='onPageLoad("/stencil-html-site-on-one-page")'>

Так выглядит, например, код примера к статье на GitHub-е.

Готовый шаблон


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

Разработку можно вести на любом статическом HTTP-сервере, установленном локально, а потом перенести «как есть» в любое место сети.

Сильные и слабые стороны


Сильные:
  • Простота, мобильность, компактность кода.
  • Нет привязки к технологиям и БД (роль БД выполняет файловая система). В основе — только открытые спецификации и стандарты.
  • Просто создавать и сопровождать резервные копии (простым копированием).

Cлабые:
  • Frondend проигрывает Backend-у по функциональности. Сложная функциональность может оказаться значительно более трудоёмкой в разработке.
  • В браузере должен быть разрешён JavaScript.

Ссылки к статье


Архитектура REST
Типы HTTP-запросов и философия REST
XMLHTTPRequest: описание, применение, частые проблемы
Основы XMLHttpRequest
DOM: работа с HTML-страницей
JavaScript HTML DOM Document
BOM Location Object
Window.location

Комментарии (32)


  1. Evgeny42
    27.05.2015 16:47
    +16

    На дворе 2007, ребята придумывают signle page application.


    1. signalizator
      27.05.2015 17:00
      +4

      В 2007 spa уже были, начало было в 2005 году.


      1. Rastishka
        28.05.2015 09:09
        +4

        IDE: Notepad

        body onload='onPageLoad()'
        А добавили бы в теги «ретро разработка» — и могли бы плюсы собрать.


        1. vedenin1980
          28.05.2015 09:17
          +3

          А если бы добавили тег «юмор»…


        1. SelenIT2
          28.05.2015 09:50
          +1

          Ну а что, Notepad действительно давал огромную гибкость и свободу по сравнению, например, с фронтпейджем (в конце 90-х еще был прикол, когда его предлагали скачать как «лучший в мире редактор для верстки BrutalHTML», да и вес архива был очень притягательным в эпоху диалапа:). Вот только с поддержкой UTF-8 без BOM у него так себе…


          1. vedenin1980
            28.05.2015 09:57
            +3

            Но какое это все имеет отношение к IDE (Интегрированной среде разработки)? Что в блокноте интегрированого-то?


            1. SelenIT2
              28.05.2015 10:29

              Он сам интегрирован в Windows =)


              1. vedenin1980
                28.05.2015 10:36

                Не, не пойдет. Вот far с плагином подсветки синтакиса и плагином ftp можно технически обозвать простейшей IDE для html/js/php.


                1. SelenIT2
                  28.05.2015 10:52
                  +2

                  Если вынести за скобки PHP, в наши дни такой IDE можно обозвать и любой браузер с Dev Tools


  1. pepelsbey
    27.05.2015 16:58
    +18

    Вы кажется забыли объяснить, зачем вы заново реализуете то, что браузеры и так умеют делать без JavaScript: запрашивать HTML-страницы по ссылкам.


    1. vedenin1980
      27.05.2015 17:30
      +1

      Не говоря уже о том что настроив переадресацию запросов в .htaccess можно сделать как бы эмуляцию signle page application, то есть пользователь будет вводить url?id=533&folder=ddd, а получать содержимое файла /ddd/553.html, да и ссылки в iframe работают без всякого JS.


      1. demimurych
        28.05.2015 02:00

        Кажется Вы не поняли иронию pepelsbey. Вопрос не в красивых ссылках, а в том какая непосредственно выгода в использовании своего собственного механизма загрузки контента.


        1. vedenin1980
          28.05.2015 10:00

          Ну выгода есть, angular'ы и backbon'ы ценны именно за собственный механизм загрузки контента, но придумывать такой топорный велосипед смысла нет никакого, уж лучше использовать классический механизм ifram'ов, он устарел лет на 15-20, но это лучше чем такой велосипед.


  1. SelenIT2
    27.05.2015 17:26
    +6

    В наши дни для реализации несложной базовой логики HTML* вообще не нужен, всё может взять на себя CSS. Вот пруф (лучше смотреть в Fx) + пояснение к нему:)

    *не говоря уж о JS


  1. zBit
    27.05.2015 17:45
    +8

    Больше похоже на хабрасуицид, если честно :)
    SPA зародились уже ооочень давно, ты опоздал с материалом лет на 10 :)

    Придирки
    Ни одна из перечисленных IDE не является IDE, это текстовые редакторы.
    Ещё и с перезагрузкой страниц…
    Ещё и в текстовых файлах…
    Ещё и вёрстка табличная…

    Ну совсем грустно ;(

    А для тех, кто понимает, что создавать свой велосипед не всегда оправдано — есть AngularJS.


  1. izac
    27.05.2015 18:54
    +3

    Прямо, хабра и машина времени.


  1. maximw
    27.05.2015 18:56
    +2

    У вас в getUrlParametr() ошибка.
    Если значение параметра содержит знак равно, то будет возращено обрезанное значение от начала до первого вхождения знака равно.
    example.com?test=123&test1=22=33=444

    console.log(getUrlParametr('test1')); // "22"
    


    1. SelenIT2
      27.05.2015 19:22

      С другой стороны, разве в значениях параметров не надо эскейпить "=" в "%3D"?


      1. maximw
        27.05.2015 19:33

        По-хорошему надо. Но работает и без эскйепа, проверял.


  1. Kano
    27.05.2015 19:48
    -2

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


    1. zBit
      27.05.2015 19:53
      +2

      Мне кажется, что по началу лучше не изобретать свои велосипеды, а учиться использовать уже существующие инструменты. Всё же создать качественный велосипед, как мне кажется, может только опытный программист и делать он это будет только при острой необходимости.
      Поэтому, совет всем новичкам: не тратьте время на это дело, лучше изучайте уже существующие инструменты.
      Ну и, ИМХО, учиться по статьям человека, который тоже учиться — плохая затея.


      1. TheShock
        28.05.2015 14:44
        +2

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


        1. vedenin1980
          28.05.2015 14:59

          Нее, это не тот велосипед, который нужно изобретать. Если бы автор попытался повторить что-то вроде angularJS (ну или хотя бы JQuery), флаг ему в руки, а в «изобретение» велосипеда с деревянными колесами ничего хорошего не даст.


    1. gonzazoid
      27.05.2015 20:57
      +3

      для новичков с азами веба это не надо — у них есть html import, custom elements, shadow dom и html templates, которые уже сейчас работают везде с полифилами, а к моменту овладения новичками азов — имхо, будут работать везде нативно.


  1. sayber
    27.05.2015 20:53
    +5

    Эта статья случайно не с времен основания хаба?
    Что то материал смахивает на оч. древний, когда люди только услышали про ajax.


    1. m0sk1t
      28.05.2015 01:51
      +3

      Долго хранилась в черновиках а тут рука дрогнула над кнопкой «Опубликовать» =)


  1. gag_fenix
    28.05.2015 14:27
    +2

    Жаль, поисковики не увидят всей этой красоты…


    1. SelenIT2
      28.05.2015 14:36
      +2

      Увидят. Поисковики нынче хитрые, в JavaScript умеют, и не только.

      Задача поисковиков — понимать страницы так, как их понимаете вы. То, что они понимают их иначе — баг, который надо исправлять. И его исправят.


    1. dshster
      28.05.2015 18:28

      Нормальные поисковики умеют видеть хеш-линки в ссылках (#!) и перенаправлять запрос на ?_escaped_fragment_=, а там уже умный сервер запускает phantomjs, который чудненько умеет исполнять javascript и выдавать результат. Angularjs так и индексируется.


  1. apelserg Автор
    29.05.2015 13:38
    +5

    У-уф — холодный душ полезен для здоровья.

    Надо признать, что большинство замечаний, даже издевательских, это правда — описанный подход не является новой технологией (об этом честно сказано в первом абзаце).

    Использую этот подход пару-тройку лет, но в интернете целостного описания или примера не нашёл. А выгода есть. Как сказал классик «Не эстетично, зато просто, дёшево и практично». Так появилась эта публикация.

    Заметки на полях:

    • Это не SPA, хотя внешне очень похоже. Есть SPA-верся, но проще и полезнее эта, например иногда хочется Shift+Ссылка.
    • Это не замена AngularJS. Если надо — Angular легко уживается внутри.
    • Это не велосипед. Велосипед не может состоять из одной функции в пять строк. А суть всего подхода — в применении функции разбора URL.
    • По-поводу табличной вёрстки. Демо не имеет отношения к дизайну, его цель — показать наглядный и целостный пример.
    • По-поводу Notepad. Профит применения дефолтных текстовых редакторов:
      • Всегда и везде под рукой, быстро открываются, не глючат, не устанавливаются по пол дня.
      • За всё время для этого проекта не потребовалось ничего сложнее (это правда).



    1. zBit
      29.05.2015 16:51
      +2

      Ещё ещё один холодный душ :)

      Это не SPA, хотя внешне очень похоже
      В заголовке написано "Сайт на основе одной HTML-страницы". Единственное, чем ваш SPA отличается от нормального SPA — перезагрузка страницы.

      Есть SPA-верся, но проще и полезнее эта, например иногда хочется Shift+Ссылка.
      Если руки совсем не кривые, то на AngularJS работает и клик средней клавишей и shift+клик по ссылке.

      Велосипед не может состоять из одной функции в пять строк
      Кто сказал? :)

      Профит применения дефолтных текстовых редакторов
      А ещё он по-дефолту сохраняет файлы в _не utf-8_, не видит unix line endings, в нём нет подсветки синтаксиса, нет автодополнений, да там вообще нифига нет, кроме поля в котором можно ввести какой-то текст :) (Мы же про Notepad, а не про Notepad++?)

      И по поводу
      быстро открываются, не глючат, не устанавливаются по пол дня
      SublimeText тоже текстовый редактор, устанавливается считанные секунды, запускается моментально, работает быстро, не глючит (без корявых плагинов), при правильном подходе прекрасно расширяется до функциональности IDE.

      Грусть, тоска, печаль…


    1. SelenIT2
      29.05.2015 17:02
      +3

      Поддерживаю за оптимизм и адекватность в ответ на критику (даже издевательскую). Дерзайте, пусть у вас получится и что-то действительно новое!

      быстро открываются, не глючат

      К сожалению, в отношении встроенного Notepad оба утверждения как минимум спорны (помимо упомянутой в комментах проблемы с UTF-8 без BOM, стоит отметить трудности открытия в нем больших файлов, плюс время от времени обнаруживаемые приколы типа старинного «Bush hid the facts»:). Моя любимая золотая середина — Notepad++ (особенно standalone-версия, не требующая установки).