要正确支持 pushSate 和非 pushState 浏览器,您需要在两种不同的状态机制之间有一个转换器。
例如,假设您的 rootURL 是“/admin/”,并且您从以下 URL 开始:
/管理员/用户/123
对于 IE8/9,您需要在 Ember 的路由机制接管之前将用户重定向到“/admin/#/users/123”。同样,如果您从此 URL 开始:
/admin/#/users/123
...那么对于支持 pushState 的浏览器,您需要在 Ember 的路由机制接管之前将状态替换为“/admin/users/123”。
这是 Backbone 路由器的默认行为,它运行良好。为了在 Ember 中实现这个结果,你可以做这样的事情,这是受到 Backbone 源代码的启发:
App.Router.reopen({
rootURL: '/admin/',
init: function () {
this.translateRoute();
this._super();
},
translateRoute: function () {
var hasPushState = window.history && window.history.pushState;
var atRoot = window.location.pathname === this.rootURL;
var fragment = decodeURIComponent(window.location.pathname);
if (!fragment.indexOf(this.rootURL))
fragment = fragment.substr(this.rootURL.length);
if (hasPushState)
this.location = 'history';
// If we started with a route from a pushState-enabled browser,
// but we're currently in a browser that doesn't support it...
if (!hasPushState && !atRoot) {
window.location.replace(this.rootURL + '#/' + fragment);
return;
}
// If we started with a hash-based route,
// but we're currently in a browser that supports pushState...
if (hasPushState && atRoot && window.location.hash) {
fragment = window.location.hash.replace(/^(#\/|[#\/])/, '');
window.history.replaceState({}, document.title, window.location.protocol + '//' + window.location.host + this.rootURL + fragment);
}
}
});