History API¶
History API — это интерфейс программирования веб-браузера, предоставляющий доступ к объекту window.history и позволяющий программно управлять сессионной историей браузера (стеком посещённых страниц) без полной перезагрузки документа. History API является частью спецификации HTML5 и ключевым компонентом для создания одностраничных приложений (SPA, Single Page Application), обеспечивая навигацию между виртуальными состояниями страницы с сохранением возможности использования кнопок «Назад» и «Вперёд», а также корректной обработки закладок.
¶Основные возможности и методы
History API предоставляет разработчикам методы для манипуляции стеком истории и чтения текущего состояния. Основными методами являются pushState(), replaceState(), а также события popstate и hashchange.
¶Метод pushState()
Метод pushState(state, title, url?) добавляет новую запись в стек истории браузера. Он принимает три аргумента:
state— объект JavaScript, содержащий произвольные данные, ассоциированные с новой записью истории. Размер объекта не должен превышать 640 КБ (ограничение, накладываемое большинством браузеров).title— строка, представляющая заголовок страницы. На практике большинство браузеров игнорируют этот параметр, поэтому часто передают пустую строку илиnull.url(необязательный) — новый URL-адрес, который будет отображаться в адресной строке браузера. URL должен быть относительным или абсолютным, но обязательно принадлежать тому же источнику (origin), что и текущая страница. Если параметр опущен, URL остаётся неизменным.
Пример использования: ``javascript const stateObj = { page: 2 }; window.history.pushState(stateObj, 'Страница 2', '/page2'); ` После выполнения этого кода в адресной строке отобразится /page2`, а в стек истории будет добавлена новая запись. Страница при этом не перезагружается.
¶Метод replaceState()
Метод replaceState(state, title, url?) заменяет текущую запись в стеке истории, а не добавляет новую. Аргументы аналогичны pushState(). Этот метод полезен, когда необходимо обновить состояние текущей страницы без создания лишних записей в истории, например, при обновлении данных формы или изменении параметров сортировки.
¶Свойства объекта history
length— количество записей в стеке истории текущей вкладки (включая текущую страницу).scrollRestoration— свойство, управляющее автоматическим восстановлением позиции прокрутки при навигации по истории. Может принимать значения'auto'(по умолчанию) и'manual'.
¶Навигационные методы
back()— переход на предыдущую страницу в истории (аналог кнопки «Назад»).forward()— переход на следующую страницу (аналог кнопки «Вперёд»).go(delta)— переход наdeltaшагов относительно текущей записи. Положительное значение — вперёд, отрицательное — назад. Например,history.go(-2)эквивалентен двукратному нажатию «Назад».
¶События
¶Событие popstate
Событие popstate генерируется объектом window при активном изменении активной записи истории. Это происходит, когда пользователь нажимает кнопки «Назад» или «Вперёд», либо при вызове методов back(), forward() или go(). Важно: методы pushState() и replaceState() не вызывают событие popstate.
Обработчик события получает объект события с полем state, содержащим данные, переданные при вызове pushState() или replaceState(). Если активная запись была создана без объекта состояния (например, при обычной навигации), state будет равен null.
Пример: ``javascript window.addEventListener('popstate', (event) => { console.log('Текущее состояние:', event.state); }); ``
¶Событие hashchange
Событие hashchange возникает при изменении хеш-части URL (всё, что идёт после символа #). Это событие является более старым механизмом, который использовался до широкого внедрения History API. Оно продолжает поддерживаться браузерами и может применяться в простых сценариях навигации, не требующих полноценного управления состояниями.
¶Применение в одностраничных приложениях
History API является фундаментом для построения SPA. В таких приложениях весь контент загружается один раз, а дальнейшая навигация осуществляется за счёт динамической подгрузки данных и изменения DOM. Без History API каждое изменение «страницы» приводило бы к потере возможности использовать кнопки «Назад» и «Вперёд», а также к некорректной работе закладок.
Типичный сценарий использования:
- При клике на ссылку или выполнении действия вызывается
pushState()с новым URL и данными состояния. - Происходит асинхронная загрузка необходимых данных (через
fetchилиXMLHttpRequest). - DOM обновляется в соответствии с новым состоянием.
- При нажатии пользователем кнопки «Назад» срабатывает событие
popstate. Обработчик извлекает данные состояния, загружает соответствующий контент и обновляет страницу.
¶Сравнение с хеш-навигацией
До появления History API для навигации в SPA часто использовалась хеш-навигация (например, example.com/#/page2). Этот подход имел недостатки:
- URL содержал символ
#, что делало адреса менее эстетичными и менее понятными для пользователей. - Хеш-часть URL не отправлялась на сервер, что затрудняло серверную обработку и индексацию поисковыми системами.
- Отсутствие поддержки произвольных объектов состояния.
History API лишён этих недостатков, позволяя использовать «чистые» URL (например, example.com/page2) и передавать произвольные данные JavaScript.
¶Ограничения и особенности
¶Политика одного источника (Same-Origin Policy)
Все операции с History API подчиняются политике одного источника. Нельзя добавить в историю URL, принадлежащий другому домену, протоколу или порту. Попытка сделать это вызовет исключение SecurityError.
¶Ограничение на размер объекта состояния
Как упоминалось выше, объект состояния не должен превышать 640 КБ в большинстве браузеров (в Firefox — 640 КБ, в Chrome — 640 КБ, в Safari — 640 КБ). Превышение этого лимита может привести к выбросу исключения QuotaExceededError.
¶Поведение при перезагрузке страницы
При перезагрузке страницы браузер восстанавливает последнюю запись истории, но не вызывает событие popstate. Для корректной обработки состояния после перезагрузки приложение должно прочитать текущий URL из location.href и на его основе инициализировать своё состояние.
¶Серверная поддержка
Для корректной работы SPA с History API необходима настройка сервера. Поскольку все запросы к виртуальным URL (например, /page2) должны возвращать один и тот же HTML-файл (точку входа приложения), сервер должен быть настроен на перенаправление всех запросов на этот файл. В противном случае при прямой загрузке example.com/page2 сервер вернёт ошибку 404.
¶Пример реализации простого роутинга
Ниже приведён упрощённый пример реализации роутинга на основе History API:
```javascript // Функция для обработки навигации function navigate(url, state = {}) { window.history.pushState(state, '', url); loadContent(url); }
// Функция для загрузки контента function loadContent(url) { // Имитация загрузки данных console.log('Загружаем контент для:', url); // Здесь может быть fetch-запрос и обновление DOM }
// Обработчик popstate window.addEventListener('popstate', (event) => { loadContent(window.location.pathname); });
// Обработчик кликов по ссылкам (перехват обычной навигации) document.addEventListener('click', (event) => { const link = event.target.closest('a'); if (link && link.href.startsWith(window.location.origin)) { event.preventDefault(); navigate(link.href); } }); ```
¶Безопасность
History API не предоставляет прямых векторов для атак, однако его неправильное использование может привести к проблемам:
- Подделка URL: злоумышленник может с помощью скрипта изменить URL в адресной строке на внешне похожий на легитимный, вводя пользователя в заблуждение. Это не является уязвимостью самого API, но требует от разработчиков осторожности при отображении URL.
- XSS-атаки: если объект состояния содержит данные, введённые пользователем, и эти данные впоследствии вставляются в DOM без надлежащей санитизации, возможна XSS-атака. Разработчики обязаны экранировать все данные, полученные из
event.state.
¶Поддержка браузерами
History API поддерживается всеми современными браузерами, включая Google Chrome, Mozilla Firefox, Apple Safari, Microsoft Edge и Opera. Поддержка в Internet Explorer ограничена версией 10 и выше (с некоторыми оговорками). Для обеспечения обратной совместимости с очень старыми браузерами можно использовать полифилы или хеш-навигацию в качестве запасного варианта.
¶История развития
История API была впервые представлена в черновике спецификации HTML5 в 2008 году. До этого разработчики были ограничены методами работы с хешем URL (window.location.hash) и событием hashchange. В 2011 году History API был реализован в браузере Firefox 4, затем в Chrome и Safari. Спецификация была стандартизирована как часть HTML Living Standard, поддерживаемого WHATWG.
¶Источники
- WHATWG HTML Living Standard — «History interface»
- MDN Web Docs — «History API»
- «Профессиональная разработка на JavaScript» — Николас Закас, глава о History API
- Спецификация W3C HTML5 — раздел «Session history and navigation»
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →

