History API и pushState

Backbone.js предоставляет мощный инструмент для работы с навигацией в одностраничных приложениях через объект Backbone.History. Он абстрагирует работу с браузерным History API и позволяет управлять URL без полной перезагрузки страницы.

Backbone.History: основы

Backbone.History отвечает за синхронизацию состояния приложения с адресной строкой браузера. Основная задача — отслеживание изменений URL и вызов соответствующих роутеров (Backbone.Router).

Ключевые особенности:

  • Поддержка hash-базированных URL (#route) и HTML5 pushState (/route).
  • Управление историей переходов, возможность перехода назад и вперед.
  • Возможность обработки пользовательских событий navigate для реактивного изменения интерфейса.

pushState: переход к современным URL

HTML5 pushState позволяет изменять адресную строку без перезагрузки страницы. Это обеспечивает чистые URL, пригодные для прямого доступа и SEO, например:

/backbone-app/users/42

В отличие от hash-фрагментов (#users/42), pushState не использует символ # и сохраняет URL в привычном виде.

Методы Backbone.History для работы с pushState:

  • start(options) — запускает отслеживание истории.
  • navigate(fragment, options) — изменяет текущий URL без перезагрузки.

Пример инициализации с pushState:

Backbone.history.start({ pushState: true });

Опция pushState: true включает поддержку HTML5 History API. Если браузер не поддерживает pushState, Backbone автоматически fallback на hash-фрагменты.

Навигация с navigate

Метод navigate управляет переходами между состояниями приложения:

router.navigate('users/42', { trigger: true });

Параметры:

  • fragment — путь URL, который будет отображаться в адресной строке.
  • options.trigger — если true, Backbone вызывает обработчик маршрута.
  • options.replace — если true, текущая запись в истории заменяется без добавления новой.

Использование trigger: true позволяет одновременно изменить URL и вызвать соответствующий метод роутера.

Примеры маршрутов с pushState

var AppRouter = Backbone.Router.extend({
  routes: {
    "users/:id": "showUser",
    "posts/:id": "showPost"
  },

  showUser: function(id) {
    console.log("Показать пользователя с ID:", id);
  },

  showPost: function(id) {
    console.log("Показать пост с ID:", id);
  }
});

var router = new AppRouter();
Backbone.history.start({ pushState: true });

Теперь переход по router.navigate('users/42', {trigger: true}) изменяет URL на /users/42 и вызывает метод showUser.

Обработка внешних ссылок

При использовании pushState важно перехватывать клики по ссылкам, чтобы браузер не перезагружал страницу:

$(document).on('click', 'a[href^="/"]', function(event) {
  event.preventDefault();
  var href = $(event.currentTarget).attr('href');
  router.navigate(href, { trigger: true });
});

Это позволяет делать навигацию полностью клиентской, сохраняя чистый URL и корректную историю браузера.

Совместимость с hashChange

Backbone автоматически использует hashChange как fallback, если браузер не поддерживает pushState. Для этого достаточно вызвать:

Backbone.history.start();

Без pushState: true Backbone будет работать с URL вида /#users/42. Это обеспечивает поддержку старых браузеров.

Взаимодействие с сервером

Для корректного использования pushState требуется настройка сервера:

  • Сервер должен отдавать основной HTML-файл для любых URL, которые обрабатываются Backbone.
  • Статические ресурсы и API должны быть доступны по отдельным маршрутам.

Это позволяет при прямом переходе по /users/42 сервер отдаёт страницу, а Backbone сам рендерит нужный контент.

Работа с replaceState

Опция replace: true позволяет обновлять текущий URL без добавления новой записи в историю:

router.navigate('users/42', { trigger: true, replace: true });

Полезно при редиректах или изменении параметров фильтров без создания лишних шагов в истории браузера.

Итоговые возможности

Использование Backbone.History и pushState позволяет:

  • Создавать одностраничные приложения с чистыми URL.
  • Обрабатывать маршруты без перезагрузки страницы.
  • Управлять историей переходов и прямыми ссылками.
  • Обеспечивать совместимость с современными и старыми браузерами.

Эта интеграция делает Backbone.js гибким инструментом для построения масштабируемой навигации в клиентских приложениях.