Надежно изменить название страницы в истории браузера с помощью JavaScript
Можно ли изменить название страницы в истории браузера через JavaScript после загрузки страницы? Должен быть кросс-браузер (конечно) и работать с браузерами, которые не поддерживают API истории HTML5, моим основным целевым браузером является Chrome.
Я пробовал ряд подходов, но никто из них, похоже, не работает надежно. Вот что я пробовал в прошлом (history.js):
<html>
<head>
<title>Standard title</title>
<script src="https://rawgit.com/browserstate/history.js/master/scripts/bundled-uncompressed/html4%2Bhtml5/native.history.js"></script>
</head>
<body>
<script>
window.setTimeout(function(){
document.title = "My custom title";
History.replaceState({}, "My custom title", window.location.href);
}, 3000);
</script>
</body>
</html>
Если я загружу страницу истории в Chrom в течение 3 секунд после загрузки страницы, я вижу Standard title
, через 3 секунды я получаю My custom title
.
Зачем мне это нужно: у меня есть приложение только для JavaScript (Angular 1), которое работает в разных средах (dev, test, production). Я хотел бы отобразить заголовок вроде MyApp (<environmentName>)
, но я не хочу создавать отдельные версии моего приложения для каждой среды. Вместо этого приложение может запрашивать информацию об окружающей среде из бэкэнд через AJAX и обновлять заголовок страницы. Все это прекрасно работает (заголовок страницы обновляется), но история браузера по-прежнему показывает "стандартное" название.
Есть ли способ изменить название страницы в истории браузера?
Ответы
Ответ 1
Короткий ответ: похоже, вы не можете хранить разные записи за один и тот же URL в Chrome.
Отказ от ответственности. Я просто наткнулся на этот вопрос и не имел никакого предыдущего опыта. Тем не менее, вопрос был настолько ясным и интересным, что я не мог не поэкспериментировать:
Прежде всего, я согласен с тем, что записи истории (т.е. названия страниц), показанные на вкладке истории, НЕ так надежны (возможно, ошибка или кеш).
Поэтому я решаю, что я буду искать файл базы данных для истории Chrome, например, используя Браузер DB для SQLite.
К моему удивлению, в истории Chrome хранится только одна версия (последняя) названия для каждого URL-адреса. И когда я делаю History.replaceState({}, "My custom title", window.location.href);
, заголовок обновляется в базе данных.
Однако метод @Bekim не изменит заголовок в базе данных.
Ответ 2
Проблема заключается в том, что второй параметр replaceState(), параметр title
, в настоящее время игнорируется практически всеми исполняющими браузерами. Тем не менее, учитывается третий параметр pushState, url
. К сожалению, он не работает с replaceState
(по крайней мере, не в Chrome или Edge, согласно моим тестам).
С учетом этого, с клиентской стороны, вы можете использовать одно из следующих обходных решений, в зависимости от вашего вкуса:
history.pushState({}, "", "my-custom-appendix");
history.pushState({}, "", "#my-custom-appendix");
В Chrome это создаст дополнительные записи с заголовком, например http://myurl/my-custom-appendix
или http://myurl/#my-custom-appendix
(соответственно). Я считаю, что это самое близкое, что вы можете получить от клиента, и побочным эффектом является то, что вы получите новую запись истории в истории браузера - для каждого посещения вашего приложения вы, по существу, увидите (в увеличении порядка отметки времени ):
Вы увидите URL как заголовок, даже если у вас есть второй параметр, установленный в непустую строку (по крайней мере, то, что происходит на моем конце).
Для более надежного подхода вам нужно будет использовать простой препроцессор AFAIK на стороне сервера, например PHP.
Ответ 3
Что самое легкое когда-либо
document.title = "My App " +environmentName;
История немедленно обновит название нового документа.
чтобы проверить его положительно, попробуйте выполнить эти несколько шагов.
1st Скопируйте в консоль следующую команду и выполните:
name = '{ "location": ["http://stackoverflow.com/questions/12689408/how-can-jquery-window-location-hash-replace","http://stackoverflow.com/questions/12978739/is-there-a-javascript-api-to-browser-history-information-limited-to-current-dom","http://stackoverflow.com/questions/24653265/angular-browser-history-back-without-reload-previous-page"],"title" : ["Page 1", "Page 2", "Page 3"]}';
document.title = "Where We've Started";
2nd Скопировать. Вставьте следующее в консоль и выполните 3 раза
nm = JSON.parse(name);
location = nm.location[0];
3rd Как только место загрузится, выполните следующие
nm = JSON.parse(name);
document.title = nm.title[0];
каждый раз, увеличивая индекс массива, как в:
location = nm.location[1];
document.title = nm.title[1];
(максимальный индекс равен 3, например, номер 2)
Затем нажмите и удерживайте кнопку "Назад", чтобы отобразить последние записи истории, все в порядке и обновлено, чтобы отразить новый заголовок документа.
Предупреждение. Если script не запущен после того, как вы вернулись к заданной записи истории, заголовок страницы вернется, как и ожидалось, к существующему жестко закодированному названию документа. Но так как эти имена контроля истории будут питаться script на всех страницах, они также будут продолжать отражать предоставленные живые документы. Здесь люди обманываются, возвращаясь к жестко закодированной странице в истории. И подумайте: "Черт, что-то пошло не так!"
Рисунок 1.: Конец результата Демо-кода, выполненного в отдельном/новом окне.
![Изображение конечного результата]()
![введите описание изображения здесь]()
Ответ 4
Относится к angularjs: -
добавить метод запуска после модуля:
.run(function ($ rootScope) {
$rootScope.$on('$stateChangeSuccess', function (evt, toState) {
window.document.title = toState.title + ' - example.com';
});
});
Ваше состояние: -
.state('productDetail', {
title: 'Details of selected product',
url: '/Detail.html',
templateUrl: '/product-details.html',
controller: 'ProductDetailsCtrl'
})
.state( 'categoryManager', {
title: 'Category Manager',
url: '/category-Manager.html',
templateUrl: 'categoryManager.html',
controller: 'categoryManagerCtrl'
});
это изменит название в соответствии с вашим состоянием.
Ответ 5
Firefox 52. Trivial:
document.title = 'CoolCmd';
Chrome 57 требует некоторой магии. Этот вариант также работает для Firefox 52. Он не добавляет лишних записей в историю браузера.
// HACK Do not change the order of these two lines!
history.replaceState(null, '');
document.title = 'CoolCmd';
MS Edge 14.14393 не позволяет изменить название документа в истории. Он даже не добавляет к истории адреса, указанные history.pushState()
! LOL
Я не тестировал Safari...
Ответ 6
Вы можете использовать document.write()
для написания правильного названия для документа на первом месте, пока он все еще загружается. Но для этого потребуется синхронный запрос на сервер:
<head>
<script>
(function () {
// Get title using sync request.
var title = "Value from server";
document.write("<title>"+ title + "</title>");
})();
</script>
</head>
Страница, которая включает отрезки сверху, появится с заголовком "Значение от сервера" в истории браузера.