假设我正在使用 Backbone pushstate,并导航到带有查询参数的页面:
domain.com/user/111?hello=123
当我执行这个:
Backbone.history.navigate('/settings', true);
我的设置页面加载完美,但 ?hello=123 保留在 URL 中...
domain.com/settings?hello=123
在我浏览网站的任何地方,该查询参数都保留在 URL 中......
假设我正在使用 Backbone pushstate,并导航到带有查询参数的页面:
domain.com/user/111?hello=123
当我执行这个:
Backbone.history.navigate('/settings', true);
我的设置页面加载完美,但 ?hello=123 保留在 URL 中...
domain.com/settings?hello=123
在我浏览网站的任何地方,该查询参数都保留在 URL 中......
骨干路由和查询参数是不愉快的结合。问题在这个 GitHub 问题中有很好的记录。
核心问题是Backbone.Router
设计用于处理 URL 哈希片段以及 pushState API。当使用哈希 URL 时,查询字符串在哈希之前,并且在路由中永远不会匹配。对于 pushState,查询字符串是 URL 片段的一部分,并且需要不同的路由表达式。
假设您有一个 route search
,并且该 route 可以选择带参数q
,sort
和type
. 作为一个查询字符串,看起来像:
search?q=kittens&sort=asc&type=images
问题是,对于旧浏览器的用户,Backbone 将恢复为hashchange
基于路由,并且路由将变为:
?q=kittens&sort=asc&type=images#search
您使用的插件试图解决这个问题,但不能解决核心问题。
如果可能,您应该考虑不使用查询字符串,并使用路由表达式中的可选片段传递任何状态信息。前面的示例路由将变为:
//pushState
search/q/kittens/sort/asc/type/images
//hash fragment
#search/q/kittens/sort/asc/type/images
使用(optional)
路由部分和:captures
( docs ),您可以使用以下表达式表示此 URL:
var Router = Backbone.Router.extend({
routes: {
"search(/q/:query)(/sort/:sort)(/type/:type)": "search"
},
search: function(query, sort, type) {
console.log(query, sort, type); //-> "kittens", "asc", "images"
}
});
只要路由片段按指定的顺序排列,这将匹配带有 none、any 和 all 参数的 url,例如:
search //-> undefined, undefined, undefined
search/q/kittens/type/images //-> "kittens", undefined, "images"
search/sort/asc/type/images //-> undefined, "asc", "images"
这样您就不必担心第三方查询字符串库或浏览器兼容性问题。如果你问我,后一种类型的 URL 看起来也更干净。
您不必再使用backbone-query-parameters
插件来处理这个问题,只需确保您拥有最新版本的 Backbone,然后覆盖loadUrl
里面的方法History.prototype
。
// Regex to match search query strings
var searchStripper = /\?.*$/g;
// Attempt to load the current URL fragment. If a route succeeds with a
// match, returns `true`. If no defined routes matches the fragment,
// returns `false`.
loadUrl: function(fragmentOverride) {
var fragment = this.fragment = this.getFragment(fragmentOverride);
fragment = fragment.replace(searchStripper, ''); // remove the search query parameter
var matched = _.any(this.handlers, function(handler) {
if (handler.route.test(fragment)) {
handler.callback(fragment);
return true;
}
});
return matched;
},
不确定是否为时已晚。我遇到了同样的问题,我可以自信地说:这是一个由主干查询参数引起的错误。
我实际上是受到你的帖子的启发。在我当前项目的早期,我引入了主干查询参数,它运行良好。但后来,主干进行了一些更改,因此主干查询参数无法再获取参数。直到最近才发现作者升级了backbone-query-parameters。我又把它拉进去了,它起作用了。
然后,你知道的。我遇到了同样的问题,感到非常沮丧。我从来没有怀疑过骨干查询参数,直到我看到你的帖子。
我删除了插件并配备了我自己的代码,现在我的历史就像一个魅力。
有许多方法可以获取 get 参数。我的只是其中之一,但它为我完成了这项工作。仅供您参考,我将其发布在这里。
getParams: ->
rtn = {}
if window.location.search.length > 0
queryStringRegex = /^\?(.*)/
match = queryStringRegex.exec window.location.search
param_string = match[1]
if param_string.length > 0
params_array = param_string.split("&")
for value in params_array
temp = value.split("=")
rtn[temp[0]] = decodeURI(temp[1])
rtn
以防万一,我的路线会是这样的
"path(?*queryString)" : "pathAction"