← Назад к вопросам
Как решать проблемы с кешированием в RTK?
1.8 Middle🔥 141 комментариев
#JavaScript Core
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Как с помощью JavaScript перейти назад по истории браузера
History API — основной инструмент
Bраузер предоставляет объект window.history, который позволяет управлять историей сессии браузера:
// Перейти на одну страницу назад (как нажать кнопку "Назад")
window.history.back();
// Перейти на одну страницу вперёд (как нажать кнопку "Вперёд")
window.history.forward();
// Перейти на N страниц назад/вперёд
window.history.go(-1); // назад на 1 страницу
window.history.go(-2); // назад на 2 страницы
window.history.go(1); // вперёд на 1 страницу
window.history.go(0); // перезагрузить текущую страницу
Различие между методами
// history.back() === history.go(-1)
window.history.back();
window.history.go(-1); // То же самое
// history.forward() === history.go(1)
window.history.forward();
window.history.go(1); // То же самое
// history.go(0) === location.reload()
window.history.go(0);
window.location.reload(); // То же самое
Практические примеры
Пример 1: Кнопка "Назад"
<!-- Простая HTML кнопка -->
<button onclick="window.history.back()">Назад</button>
<!-- Или с JavaScript обработчиком -->
<button id="back-btn">Назад</button>
<script>
document.getElementById('back-btn').addEventListener('click', () => {
window.history.back();
});
</script>
Пример 2: Проверка наличия предыдущей страницы
// К сожалению, нельзя напрямую узнать длину истории из соображений безопасности
// Но можно проверить, может ли пользователь вернуться назад
function canGoBack() {
// Это НЕ рабочий способ (браузер не предоставляет доступ)
// Нужна альтернатива...
}
// Лучший подход: попробовать вернуться и отловить ошибку
function safeGoBack() {
try {
window.history.back();
} catch (error) {
// Ошибки не будет, но можно добавить fallback
window.location.href = '/';
}
}
Пример 3: Условный переход
// Перейти назад, если есть реферер
if (document.referrer) {
// Пользователь пришёл со страницы сайта
window.history.back();
} else {
// Пользователь пришёл прямо (или через поисковик)
window.location.href = '/home';
}
History API — более мощный инструмент
Для управления историей можно использовать методы pushState и replaceState:
// Добавить новую запись в историю БЕЗ перезагрузки страницы
window.history.pushState(
{ page: 1 }, // State object
'Page 1', // Title
'/page-1' // URL
);
// Заменить текущую запись в истории
window.history.replaceState(
{ page: 2 },
'Page 2',
'/page-2'
);
// Теперь нажатие "Назад" вернёт на /page-1
window.history.back();
Пример: Single Page Application навигация
class Router {
constructor() {
this.routes = {};
this.currentPath = window.location.pathname;
// Слушаем события когда пользователь нажимает "Назад"
window.addEventListener('popstate', (e) => {
const path = e.state?.path || window.location.pathname;
this.navigate(path, false);
});
}
register(path, handler) {
this.routes[path] = handler;
}
navigate(path, addToHistory = true) {
const handler = this.routes[path];
if (!handler) {
console.error(`No route for ${path}`);
return;
}
// Выполняем обработчик маршрута
handler();
// Добавляем в историю
if (addToHistory) {
window.history.pushState(
{ path },
document.title,
path
);
}
this.currentPath = path;
}
}
// Использование
const router = new Router();
router.register('/', () => {
document.body.innerHTML = '<h1>Home</h1>';
});
router.register('/about', () => {
document.body.innerHTML = '<h1>About</h1>';
});
router.register('/contact', () => {
document.body.innerHTML = '<h1>Contact</h1>';
});
// Навигация
document.getElementById('home-link').addEventListener('click', (e) => {
e.preventDefault();
router.navigate('/');
});
document.getElementById('about-link').addEventListener('click', (e) => {
e.preventDefault();
router.navigate('/about');
});
// Нажатие "Назад" автоматически вернёт на предыдущий маршрут
React пример с использованием History
import { useHistory } from 'react-router-dom';
function GoBackButton() {
const history = useHistory();
return (
<button onClick={() => history.goBack()}>
Назад
</button>
);
}
// Для более новых версий React Router (v6+)
import { useNavigate } from 'react-router-dom';
function GoBackButton() {
const navigate = useNavigate();
return (
<button onClick={() => navigate(-1)}>
Назад
</button>
);
}
Проверка перед переходом
// Предупредить пользователя перед переходом
window.addEventListener('beforeunload', (e) => {
if (hasUnsavedChanges) {
e.preventDefault();
e.returnValue = 'У вас есть несохранённые изменения';
return false;
}
});
// Теперь при попытке вернуться назад появится окно с подтверждением
popstate событие — реакция на нажатие "Назад"
window.addEventListener('popstate', (event) => {
// event.state содержит данные, которые мы сохранили в pushState
console.log('User clicked back button', event.state);
if (event.state?.page) {
loadPage(event.state.page);
}
});
// Когда пользователь нажимает "Назад", это событие срабатывает
// Очень полезно для SPA приложений
Ограничения и соображения безопасности
Ограничение 1: Нельзя узнать длину истории
// Этот код НЕ работает (браузер не позволяет)
console.log(window.history.length); // Выведет количество в истории
// Но это число может быть неточным и браузер может ограничить доступ
Ограничение 2: Нельзя видеть URL в истории
// Этот код НЕ работает (безопасность!)
console.log(window.history[0]); // undefined
console.log(window.history[-1]); // undefined
// Браузер скрывает эту информацию в целях безопасности
Ограничение 3: Нельзя программно перейти на конкретный URL из истории
// Этот код НЕ работает
window.history.go('/specific-url'); // ошибка
// window.history.go() принимает только числа!
window.history.go(-1); // ✅ правильно
window.history.go(5); // ✅ правильно
Лучшие практики
// ✅ ПРАВИЛЬНО
// Использовать history.back() для простой навигации
function handleGoBack() {
window.history.back();
}
// Использовать pushState для SPA
window.history.pushState({ data }, 'Title', '/new-path');
// Слушать popstate события
window.addEventListener('popstate', handleHistoryChange);
// ❌ НЕПРАВИЛЬНО
// Предполагать, что знаешь состояние истории
if (window.history.length > 1) {
// Это может быть неточно
}
// Пытаться модифицировать history напрямую
window.history[0] = 'fake'; // Не работает
// Забыть отписаться от popstate события
// (может привести к утечкам памяти)
Реальный пример: форма с подтверждением
class FormWithUndo {
constructor(formElement) {
this.form = formElement;
this.originalState = null;
this.setupListeners();
}
setupListeners() {
// Сохранить исходное состояние
this.form.addEventListener('focusin', () => {
if (!this.originalState) {
this.originalState = new FormData(this.form);
}
});
// Предупредить при уходе
window.addEventListener('beforeunload', (e) => {
if (this.hasChanges()) {
e.preventDefault();
e.returnValue = 'Вы уверены?';
}
});
// Восстановить при возврате
window.addEventListener('popstate', () => {
this.restoreFormState();
});
}
hasChanges() {
const currentState = new FormData(this.form);
return JSON.stringify(this.originalState) !== JSON.stringify(currentState);
}
restoreFormState() {
if (this.originalState) {
const entries = this.originalState.entries();
for (const [name, value] of entries) {
const input = this.form.elements[name];
if (input) input.value = value;
}
}
}
}
Выводы
- window.history.back() — самый простой способ вернуться назад
- window.history.go(n) — перейти на n страниц в историю
- pushState/replaceState — для управления историей в SPA
- popstate событие — слушай это для реакции на "Назад"
- Безопасность — браузер скрывает детали истории для защиты приватности
- Нельзя узнать URL из истории — браузер это запрещает
- Используй разумно — не злоупотребляй историей для манипуляции пользователем