# Firefox 历史记录弹出窗口中的标题错误

**URL:** https://meta.discourse.org/t/wrong-title-in-the-history-popup-firefox/203020
**Category:** Bug
**Tags:** pr-welcome
**Created:** [2021年九月8日 22:15 UTC](https://meta.discourse.org/t/wrong-title-in-the-history-popup-firefox/203020 "2021-09-08T22:15:40Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![lutin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/lutin/32/213651_2.png) [@lutin](https://meta.discourse.org/u/lutin)
#### Post date: [2021年九月8日 22:15 UTC](https://meta.discourse.org/t/wrong-title-in-the-history-popup-firefox/203020/1 "2021-09-08T22:15:40Z")

</div>

您好，  
在 Firefox 中，右键点击“上一页”箭头时显示的上一页标题会被当前页面标题覆盖。

例如，如果首先显示的页面是：  
[https://meta.discourse.org/](https://meta.discourse.org/)  
查看右键点击箭头时的显示效果（这是正确的）：

 ![IMG00224-20210909-0011](https://global.discourse-cdn.com/meta/original/3X/d/c/dc4093e8054cfbe53d8f103713085cb1db711309.jpeg)

然后进入任意主题，例如：

> [@DiscoTOC - automatic table of contents](https://meta.discourse.org/t/discotoc-automatic-table-of-contents/111143):
>
> discourse2Summary DiscoTOC will allow you to generate an interactive table of contents for your topics with one click!eyeglassesPreview [Preview on Discourse Theme Creator](https://discourse.theme-creator.io/theme/Discourse/discotoc)hammer_and_wrenchRepository Link [https://github.com/discourse/DiscoTOC](https://github.com/discourse/DiscoTOC)open_bookNew to Discourse Themes? [Beginner’s guide to using Discourse Themes](https://meta.discourse.org/t/beginners-guide-to-using-discourse-themes/91966) Install this theme component Samples Desktop Mobile Features toc = table of contents Automatically generates the …

此时，“上一页”的标题已被当前页面标题覆盖：

 ![IMG00225-20210909-0011](https://global.discourse-cdn.com/meta/original/3X/6/2/6209b0d6cb0ad338b6054a4b03fc2241965491e5.jpeg)

不过，链接仍然有效。

---

<div class="post-metadata">

### Author: ![lutin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/lutin/32/213651_2.png) [@lutin](https://meta.discourse.org/u/lutin)
#### Post date: [2021年十一月1日 14:17 UTC](https://meta.discourse.org/t/wrong-title-in-the-history-popup-firefox/203020/2 "2021-11-01T14:17:19Z")

</div>

对这个问题有什么想法吗？

---

<div class="post-metadata">

### Author: ![sam](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sam/32/102149_2.png) [@sam](https://meta.discourse.org/u/sam)
#### Post date: [2021年十一月2日 01:12 UTC](https://meta.discourse.org/t/wrong-title-in-the-history-popup-firefox/203020/3 "2021-11-02T01:12:35Z")

</div>

这确实看起来像是一个 bug，可能与我们替换历史记录的方式或顺序有关，或者是 Firefox 的一个特性。

我已能够复现该问题。

由于问题相对较小，我将添加一个 #pr-welcome 标签，以便社区成员如有意愿可以参与并提出修复方案。

---

<div class="post-metadata">

### Author: ![lutin](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/lutin/32/213651_2.png) [@lutin](https://meta.discourse.org/u/lutin)
#### Post date: [2021年十一月2日 08:25 UTC](https://meta.discourse.org/t/wrong-title-in-the-history-popup-firefox/203020/4 "2021-11-02T08:25:30Z")

</div>

好的，谢谢您的回答。

---

<div class="post-metadata">

### Author: ![eitau](https://avatars.discourse-cdn.com/v4/letter/e/85e7bf/32.png) [@eitau](https://meta.discourse.org/u/eitau)
#### Post date: [2023年十月11日 14:41 UTC](https://meta.discourse.org/t/wrong-title-in-the-history-popup-firefox/203020/5 "2023-10-11T14:41:13Z")

</div>

我发现此 bug 也会导致浏览历史记录中的历史条目有些损坏，我认为这是一个更严重的问题。更具体地说，当导航由 JS 处理时，旧 URL 会被分配一个新标题。在 Firefox 中几乎总是会发生这种情况，但在 Chrome 中却很少见（到目前为止我只发现了一个实例：从 `/top` 进入一个主题）。

 ![title-url-chrome-and-firefox](https://global.discourse-cdn.com/meta/original/4X/6/8/6/686cdc8bffee797ff20669e316af013a3625ceff.png)

@sam 说得对，这是由修改 URL 和标题的操作顺序引起的。我希望有某种最佳实践指南发布在某个地方，说明正确的顺序是什么：始终在`history`API 之后更新标题。

我尝试进行了一些调试（我想提前说明，我非常不愿构建任何中等规模的 _npm 相关_ 项目）。最初，我使用了以下代码进行了一些侦察：

```javascript
Object.defineProperty(document, "title", {
  get() {
    return document.head.querySelector('title').innerText;
  },
  set(t) {
    console.debug('title', t, new Error("title!").stack)
    debugger;
    document.head.querySelector('title').innerText = t;
  },
  enumerable: true,
  configurable: true,
});
let ___push___ = window.history.pushState;
window.history.pushState = function(...args) {
  console.debug('push', args[0], new Error().stack);
  debugger;
  ___push___.apply(this, args);
};

let ___replace___ = window.history.replaceState;
window.history.replaceState = function(...args) {
  console.debug('replace', args[0], new Error().stack);
  debugger;
  ___replace___.apply(this, args);
};

```

它确实表明，在`history`API 操作之前，几乎总会有一个标题修改。不幸的是，它没有提供更多帮助：将运行时发生的事情与源代码联系起来非常困难——感兴趣的操作分散得相当厉害，调用堆栈具有误导性，因为执行已经让步给了 Ember 的事件循环，而且总的来说，Firefox 中的调试体验非常糟糕。切换到 Chrome 后，我取得了一些成功。长话短说，据我所知，Ember 会自行决定何时更新 URL。另一方面，标题的修改可以从两个地方发起：[1] 和 [2]

只有后者在`history`API 调用之前执行。它们“共同的代码祖先”位于此处：

> <https://github.com/tildeio/router.js/blob/9320c7b1c1e887e73afd3700cd0093b9f34c9e6b/lib/router/router.ts#L364-L374>

```javascript
// Run all the necessary enter/setup/exit hooks
this.setupContexts(newState, transition); // <-- title change initiated here, by triggering `model.title:change` event

// Check if a redirect occurred in enter/setup
if (transition.isAborted) {
  // TODO: cleaner way? distinguish b/w targetRouteInfos?
  this.state!.routeInfos = this.currentRouteInfos!;
  return Promise.reject(logAbort(transition));
}

this._updateURL(transition, newState); // <-- url change initiated here

```

有趣的是，“router.js 是 Ember.js 使用的路由微库。”

现在我想将处理此问题的工作交给一个与 `discourse` 代码库有远程熟悉的人，而不是我。

编辑：忘记提了：`document.title`在（两者）被修改[2]和 URL 被 `history` API 修改之后，被[1]修改了一次或多次。

---

<div class="post-metadata">

### Author: ![eitau](https://avatars.discourse-cdn.com/v4/letter/e/85e7bf/32.png) [@eitau](https://meta.discourse.org/u/eitau)
#### Post date: [2023年十月11日 14:41 UTC](https://meta.discourse.org/t/wrong-title-in-the-history-popup-firefox/203020/6 "2023-10-11T14:41:45Z")

</div>

（作为新用户，我每帖只能放 2 个链接 ☹ ）

[1] ([discourse/app/assets/javascripts/discourse/app/lib/page-tracker.js at 245e9f30a4825beb86fcbfcf718208752748e5b4 · discourse/discourse · GitHub](https://github.com/discourse/discourse/blob/245e9f30a4825beb86fcbfcf718208752748e5b4/app/assets/javascripts/discourse/app/lib/page-tracker.js#L35))

[2] ([discourse/app/assets/javascripts/discourse/app/controllers/topic.js at 542f77181a47df8aa0f909f69814406491d08c5e · discourse/discourse · GitHub](https://github.com/discourse/discourse/blob/542f77181a47df8aa0f909f69814406491d08c5e/app/assets/javascripts/discourse/app/controllers/topic.js#L141))
