通过 JavaScript 可靠地更改浏览器历史记录中的页面标题

Reliably change page title in browser history via JavaScript

是否可以在页面加载后通过JavaScript更改浏览器历史记录中的页面标题?应该是 cross-browser(当然)并且在不支持 HTML5 历史记录 API 的浏览器上工作,我的主要目标浏览器是 Chrome.

我尝试了多种方法,但其中 none 似乎工作可靠。这是我最后尝试过的 (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>

如果我在页面加载后 3 秒内在 Chrom 中加载历史页面,我会看到 Standard title,3 秒后我会看到 My custom title

为什么我需要这个:我有一个在不同环境(开发、测试、生产)上运行的 JavaScript-only 应用程序 (Angular 1)。我想显示像 MyApp (<environmentName>) 这样的标题,但我不想为每个环境构建我的应用程序的单独版本。相反,应用程序可以通过 AJAX 从后端请求环境信息并更新页面标题。所有这些工作正常(页面标题得到更新),但浏览器历史记录仍然显示 "standard" 标题。

是否也可以更改浏览器历史记录中的页面标题?

问题是考虑了 replaceState(), the title parameter, is currently ignored by essentially all implementing browsers. However, the third parameter on pushStateurl 的第二个参数。不幸的是,它不适用于 replaceState(根据我的测试,至少在 Chrome 或 Edge 中无效)。

考虑到这一点,从客户端,您可以使用以下解决方法之一,无论您喜欢哪种:

history.pushState({}, "", "my-custom-appendix");
history.pushState({}, "", "#my-custom-appendix");

在 Chrome 中,这将创建标题为 http://myurl/my-custom-appendixhttp://myurl/#my-custom-appendix(分别)的其他条目。我相信这是您可以从客户端获得的最接近的结果,副作用是您将在浏览器历史记录中获得一个新的历史条目——每次访问您的应用程序时,您基本上都会看到(按时间戳顺序递增) ):

即使您将第二个参数设置为 non-empty 字符串,您也会看到 URL 作为标题(至少我这边是这样)。


要获得更可靠的方法,您需要使用简单的 server-side 预处理器 AFAIK,例如 PHP.

您可以使用 document.write() 在文档仍在加载时首先将正确的标题写入文档。但它需要向服务器同步请求:

<head>
  <script>
  (function () {
    // Get title using sync request.
    var title = "Value from server";
    document.write("<title>"+ title + "</title>");
  })();
  </script>
</head>

包含上述片段的页面将在浏览器历史记录中以 "Value from server" 标题出现。

这是有史以来最简单的事情

document.title = "My App " +environmentName;

历史会立即更新新的文档标题。


为了能够对其进行正面测试,请尝试执行以下几个步骤。

1st 将以下内容复制粘贴到您的控制台并执行:

name = '{ "location": ["http://whosebug.com/questions/12689408/how-can-jquery-window-location-hash-replace","http://whosebug.com/questions/12978739/is-there-a-javascript-api-to-browser-history-information-limited-to-current-dom","http://whosebug.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 Copy-Paste 在你的控制台执行以下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,例如 num 2)
比单击并按住“后退”按钮以显示最新的历史条目更完整和更新以反映新的文档标题。

警告:如果脚本不是 运行 在您退回到给定的历史记录条目后,页面标题将按预期恢复为现有的 hard-coded 文档标题。但是由于此历史控件名称将由所有页面中的脚本提供,因此它们还将继续反映提供的实时文档标题。这就是人们在回到历史上的 hard-coded 页面时被骗的地方。并思考:"damn: something went wrong!"

图 1.:在单独的/新的 window 上执行的演示代码的最终结果。

与angularjs相关:-

在模块后添加运行方法:-

.运行(函数($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'
   
  });

这将根据您所在的州更改标题。

简短回答:似乎无法在 Chrome.

中为相同的 url 保留不同的标题记录

免责声明:我只是偶然发现了这个问题,之前对此没有任何经验。尽管如此,这个问题是如此清晰和有趣,以至于我忍不住做了一些实验:

首先,我同意历史选项卡中显示的历史记录(即页面标题)不是那么可靠(可能是错误或缓存)。

所以我决定查看数据库文件以获取 Chrome 历史记录,例如,使用 DB Browser for SQLite.

令我惊讶的是,Chrome 历史记录只为每个 url 保留一个版本(最新)的标题。当我这样做时 History.replaceState({}, "My custom title", window.location.href);,标题会在数据库中更新。

但是,@Bekim 的方法不会更改数据库中的标题。

Firefox 52。琐碎的:

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() 指定的地址添加到历史记录中!哈哈

我没有测试 Safari...