使用rails登录骨干路由后重定向

时间:2014-10-17 16:56:13

标签: ruby-on-rails angularjs backbone.js

我正在尝试为用户提供一个通用功能,在登录到安全路径后面最初请求的URL后重定向它们。例如,用户单击通过系统中的通知触发的电子邮件中的链接,尝试转到: https://mysite.com/secure/notifications/1 用户未登录,因此被踢回去 https://mysite.com/login 登录后,他们不应该被带到他们的主页,而是到最初请求的网址。

我很熟悉在重定向到登录页面之前将尝试的URL存储在会话中的技术。问题是如果URL包含核心URL之后的骨干路由器,即 https://mysite.com/secure/notifications/1#details

URL的#details部分似乎没有发送到服务器,因为这通常用于内页跳转。我想知道Web开发人员如何处理这个像MV MVC框架如骨干,角度和其他正在出现?一些技巧?在http规范中实际拥有#pass到服务器的任何方法吗?

任何想法都表示赞赏,谢谢。

2 个答案:

答案 0 :(得分:1)

对于此问题,最简单的解决方案是,如果您不需要为旧版浏览器支持此行为,则应在您的骨干路由器中启用pushState,这样您就不会将#用于路由:

Backbone.history.state({pushState: true});

修改

另一个可能的解决方案,虽然有点混乱,但是要做一些URL tomfoolery来弄清楚哈希之后应该是什么,然后导航到那条路线。

例如,让我们说你要导航到:

http://webapp.com/abc/#page1其中' page1'是构成Backbone路由的片段。

如果您将用户发送到http://webapp.com/abc/page1。您可以检测浏览器是否具有pushState。如果没有,您可以在' root'之后替换所有内容。用哈希。下面是一些示例代码,可以帮助您在正确的轨道上支持两组浏览器:



    var _defaults = {
      pushState: Modernizr.history,
      silent: true,
      root: '/'
    };

    var start = function(options) {
      // Start the routing either with pushstate or without
      options = _.extend(_.clone(this._defaults), options);
      Backbone.history.start(options);
      if (options.pushState) {
        Backbone.history.loadUrl(Backbone.history.getFragment());
        return;
      }
      this.degradeToNonHistoryURL();
    };

    /**
     * For fragment URLs, we check if the actual request is for the root i.e '/',
     * If it is, we can continue and Backbone will do the magic
     * If it isn't we redirect to the root with the route as a fragment
     * foo.com/bar/1 -> foo.com/#bar/1
     */
    degradeToNonHistoryURL = function() {
        var pathName = window.location.pathname;

        // If the root is '/', length is one. If the root is 'foo', length is 5 (/foo/)
        var rootLength = _getRoot().length;
        var isRootRequest = pathName.length === rootLength;
        if (!isRootRequest) {
          var route = pathName.substr(rootLength);
          window.location.href = _getRoot() + '#' + route + window.location.search;
          return;
        }
        Backbone.history.loadUrl(Backbone.history.getFragment());
      },

      /**
       * Get the effective root of the app. Normally it's '/', but if set to 'foo', we want
       * to return '/foo/' so we can more easily determine if this is a root request or not.
       * @returns {String} The effective root
       */
      _getRoot = function() {
        if (Backbone.history.options.root === '/') {
          return '/';
        }
        return '/' + Backbone.history.options.root + '/';
      },




这里的技巧是将pushState URL设置为规范URL,并始终将用户发送给那些URL。一旦浏览器采用率增加,理论上很容易在不更新所有链接的情况下减少所有这些废话。

答案 1 :(得分:0)

经过一些研究,似乎只有两种解决方案

  1. 根据Will的推荐,使用pushState并且仅支持HTML5浏览器,但这对使用hash或hashbang javascript导航的现有应用程序进行了大量更改。

  2. 服务器端的变通方法,这里的主要选项是提供重定向端点,以便用户获取需要去的地方。例 / MyApp的/重定向pathroot =通知&安培; hashroot =详细资料和hashparam1 = 2 这将在服务器端建立一个URL / MyApp的/通知/ 1#细节/ 2

  3. 因此在#2中,服务器无法使用主题标签接收http请求,但是它可以发送它们。浏览器将收到这个完整的路径,包括哈希导航部分,并执行其正常的javascript MVC路由事件。