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

Hello,
in Firefox, the previous page title that appears with a right clic on the “previous page” arrow is overwritten with the current page title.

For instance, if the first page displayed is:
https://meta.discourse.org/
see what the right click on arrow looks like (it is correct):

then going on any topic, such as:

the title of the previous page has been overwritten with the current page title:

Nevertheless, the link is still valid.

any idea about this bug?

It does indeed look like a bug possibly in the way / sequence that we replace history or a firefox quirk.

I am able to reproduce.

Since it is fairly minor I am going to put a pr-welcome in case the community would like to pitch in and propose a fix.

alright, thanks for your answer

我发现此 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 个赞