在Firefox中,骨干导航触发两次

时间:2013-07-18 15:18:13

标签: firefox backbone.js url-routing

尝试使用Backbone的导航属性。

 this.navigate("week/" + companyName + "/" + employeeNo + "/" + weekEnd, { trigger: true, replace: false });

上面的代码执行一次。

它击中了这个:

routes: {
    "week/:companyName/:employeeNo/:weekEnd": "getWeek"
},

然后这个函数被击中两次:

getWeek: function (companyName, employeeNo, weekEnd) {
    console.log('getWeek:', companyName, employeeNo, weekEnd);
 }

在Firefox中记录两次,在IE和Chrome中只记录一次。

这里有什么问题?我原本甚至没有将触发器设置为true,并且Firefox忽略了它并仍然触发了URL。

3 个答案:

答案 0 :(得分:6)

最近我遇到类似的问题,Firefox在Backbone.navigate之后进行了两次服务器调用。在我的情况下,这是因为我们没有编码字符串。您的公司名称是否包含任何应编码的字符?

你可以尝试:

this.navigate("week/" + escape(companyName) + "/" + employeeNo + "/" + weekEnd, { trigger: true, replace: false });

答案 1 :(得分:4)

随着我遇到同样的问题而陷入困境,并在此处解决了潜在的问题。

如前所述,问题来自URL编码。现在问题为什么这个问题只出现在Firefox ......

让我们首先快速总结一下当哈希值发生变化时如何调用路由。这里有3个关键功能:

  • loadUrl :此函数将调用您的路由处理程序。
  • 导航:这是用于手动更改路线的功能。如果触发器标志设置为 true ,则该函数将调用 loadUrl
  • checkUrl :此函数设置为窗口对象上 onhashchange 事件的回调(当然它可用时) )。它还在某些条件下运行 loadUrl

现在,我们正在进入有趣的部分。

当您运行导航时,Backbone将缓存您导航到的片段。哈希更改, checkUrl 也将被调用。然后,此函数将检查缓存的哈希值是否等于当前哈希值,以便在之前调用导航时不执行 loadUrl ,因为这意味着它已被调用。要进行比较, checkUrl 会使用 getFragment 函数获取当前哈希值,该函数使用 getHash 。这是 getHash 的代码:

getHash: function(window) {
  var match = (window || this).location.href.match(/#(.*)$/);
  return match ? match[1] : '';
},

你遇到了问题。 location.href 在Firefox中进行URI编码,但不在chrome中。因此,如果您导航到另一个哈希(有或没有 触发器标志),在Firefox中,Backbone将缓存哈希的未编码版本,然后将其与编码进行比较版。如果你的哈希包含一个应该编码的字符,那么比较的结果将是负数,Backbone将执行它不应该执行的路由处理程序。

根据解决方案,好吧,人们之前说过,你的URI应该被编码。

答案 2 :(得分:0)

问题可能已经过时了,但对我来说,这仍然是相关的。在我的情况下,对网址进行编码是不够的。我用Backbone替换了Backbone中的GetHash()函数:

getHash: function (t) { 
    var e = (t || this).location.href.match(/#(.*)$/);
    return match ? this.decodeFragment(match[1]) : '';
}