3

我的印象是 Ember 在一些旧版本的 IE 下经过了很好的测试。但是,在最终启动我接近完整的应用程序(表单向导)时。我注意到 IE 抱怨 replaceState 和 pushState,根据http://caniuse.com/#search=pushState这两种方法不受支持

有什么解决方法吗?

SCRIPT438: Object doesn't support property or method 'replaceState'

get(this, 'history').replaceState(state, null, path);

4

3 回答 3

10

更新:从 Ember 1.5.0+ 开始,我可以确认他们添加了“自动”,这应该消除对下面示例的需要。

App.Router.reopen({
  location: 'auto'
});

原答案:

显然,您需要对历史 API 进行功能检测:

if (window.history && window.history.pushState) {
  App.Router.reopen({
    location: 'history'
  });
}
于 2013-09-07T02:05:22.657 回答
0

没有解决办法。如果您需要使用真实 URL (/users) 而不是哈希 URL (/#/users),那么您必须从支持的浏览器列表中排除 IE 8 和 9,或者您需要在“渐进式增强”中使用 Ember方式,仍然为访问的每个真实 URL 提供来自服务器的有效内容,并使用功能检测来选择性地启用您的 Ember 应用程序。

于 2013-09-07T03:31:58.320 回答
0

要正确支持 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);
        }
    }
});
于 2014-06-12T17:52:29.137 回答