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

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

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

然后进入任意主题,例如:

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

不过,链接仍然有效。

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

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

我已能够复现该问题。

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

好的,谢谢您的回答。

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

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

我尝试进行了一些调试(我想提前说明,我非常不愿构建任何中等规模的 npm 相关 项目)。最初,我使用了以下代码进行了一些侦察:

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);
};

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

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

// 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]修改了一次或多次。

1 个赞

(作为新用户,我每帖只能放 2 个链接 :frowning:

[1] (discourse/app/assets/javascripts/discourse/app/lib/page-tracker.js at 245e9f30a4825beb86fcbfcf718208752748e5b4 · discourse/discourse · GitHub)

[2] (discourse/app/assets/javascripts/discourse/app/controllers/topic.js at 542f77181a47df8aa0f909f69814406491d08c5e · discourse/discourse · GitHub)

1 个赞