22

通过在 AngularJS 中启用 HTML5 模式,$location服务将重写 URL 以从中删除 hashbang。这是一个很棒的功能,可以帮助我处理我的应用程序,但是它回退到 hashbang 模式存在问题。我的服务需要身份验证,我被迫从我的应用程序中使用外部身份验证机制。如果用户尝试访问带有 hashbang 的应用程序的 URL,它将首先将他们重定向到身份验证页面(除非成功通过身份验证,否则永远不会接触我的服务),然后将他们重定向回我的应用程序。由于哈希标签只能从客户端看到,所以当它们到达我的服务器时,它会丢弃路由的任何部分。一旦他们通过身份验证,他们可能会重新输入 URL 并且它会起作用,但它是第一次会导致用户体验中断。

那么我的问题是,有没有什么办法可以从不$location.html5Mode(true)支持的浏览器的全页面重新加载的回退,跳过完全在 AngularJS 中路由的 hashbang 方法?

我的目标可用实现的最佳比较是诸如浏览 github.com 上的文件夹之类的东西。如果浏览器支持在不启动页面刷新的情况下重写 URL,则页面将异步加载必要的部分。如果浏览器不支持,当用户点击文件夹时,会发生整页刷新。这可以用 AngularJS 代替使用 hashbang 模式来实现吗?

4

4 回答 4

2

不要覆盖核心功能。

使用 Modernizr,进行特征检测,然后进行相应的操作。

检查历史 API 支持

if (Modernizr.history) {
  // history management works!
} else {
  // no history support :(
  // fall back to a scripted solution like History.js
}
于 2014-09-22T07:06:18.927 回答
1

尝试在浏览器的 HTML5 History API 检查中包装 $location 和 $routeProvider 配置,如下所示:

if (isBrowserSupportsHistoryAPI()) {
    $location.html5Mode(true)
    $routeProvider.when(...);
}

如果您使用它来更改路径,您可能还需要为 $location 创建一个包装器。(对不起糟糕的英语)

于 2013-03-28T12:24:46.813 回答
1

您可以尝试覆盖 $location 服务的功能。一般的想法是根据某人是否已经过身份验证来重写 URL,或者只对所有 URL 使用单一方法(没有 hashbang),而不管 html5mode 是否打开。

我不确定我是否完全理解用例,所以我无法编写您需要的确切代码。以下是如何覆盖/实现和注册 $location 服务的示例实现,只需确保始终消除 hashbang:

app.service('$location', [function() {
    var DEFAULT_PORTS = {
        ftp: 21,
        http: 80,
        https: 443
    };

    angular.extend(this, {
        absUrl: function() {
            return location.href;
        },
        hash: function(hash) {
            return location.hash.substr(1);
        },
        host: function() {
            return location.host;
        },
        path: function(path) {
            if (!path) {
                return location.pathname;
            }
            location.pathname = path;
            return this;
        },
        port: function() {
            return location.port ? Number(location.port) : DEFAULT_PORTS[this.protocol()] || null;
        },
        protocol: function() {
            return location.protocol.substr(0, location.protocol.length - 1);
        },
        replace: function() {
            return this;
        },
        search: function(search, paramValue) {
            if (search || paramValue) {
                return this;
            }
            var query = {};
            location.search.substr(1).split("&").forEach(function(pair) {
                pair = pair.split("="); query[pair[0]] = decodeURIComponent(pair[1]);
            });
            return query;
        },
        url: function(url, replace) {
            return this.path();
        }
    });
}]);
于 2014-06-09T22:21:13.063 回答
1

对于这种情况,为什么不在客户端处理未经身份验证的重定向?我需要更多地了解您的应用程序是如何工作的,以便为您提供更具体的解决方案,但本质上是这样的:

  1. 用户转到由 AngularJS 处理的路由,服务器提供 AngularJS 主模板和 javascript
  2. 用户未通过身份验证,AngularJS 检测到这一点并重定向到身份验证页面

当 AngularJS 应用程序启动时,您可以在模块的运行块中包含一些内容:

module('app',[])
  .configure(...yadda...yadda...yadda...)
  .run(['$location', 'authenticationService', function($location, auth) {
    if (!auth.isAuthenticated()) {
      $location.url(authenticationUrl) 
    }
  });

我已经加入了一项服务,该服务会查明您是否以某种方式通过了身份验证,取决于您如何检查会话 cookie,可能会点击您的 API 来询问。真正取决于您希望在客户端应用程序运行时如何继续检查身份验证。

于 2013-09-30T20:15:45.600 回答