当path包含查询字符串时,使用returnUrl重定向的问题

时间:2015-05-19 20:07:25

标签: angularjs

我有以下授权拦截器,当401发生时,它会将用户重定向到我的登录路由:

app.factory('authHttpResponseInterceptor', ['$q', '$location', function ($q, $location) {
    return {
        response: function (response) {
            if (response.status === 401) {
                console.log("Response 401");
            }
            return response || $q.when(response);
        },
        responseError: function (rejection) {
            if (rejection.status === 401 && $location.path() !== '/') {
                $location.path('/login').search('returnUrl', $location.path());
            }
            return $q.reject(rejection);
        }
    }
}]);

我希望它将用户尝试访问的URL设置为returnURL。不幸的是,如果网址类似于/join?code123&id=456,则会重定向到/login?code123&id=456&returnUrl=%2Flogin。正如您所看到的,它将查询字符串保留在查询字符串中,而不是将其包含在returnUrl中。

然后我想在重定向中使用$location.url(),如下所示:

$location.path('/login').search('returnUrl', $location.url());

...确实将完整的查询字符串放在returnUrl中,但查询字符串仍然保留在这样的路径中:/login?code123&id=456&returnUrl=%2Flogin%3Fcode%3D123%26id%3D456。 AFAIK,要从查询字符串中删除项目,您必须手动清除它们(例如$location.path().search('code', null)),这是不正确的。

提前致谢。

1 个答案:

答案 0 :(得分:0)

我最终以稍微不同的方式解决了这个问题。

我摆脱了returnUrl代码,这样我的拦截器的responseError看起来像这样:

responseError: function (rejection) {
    if (rejection.status === 401 && $location.path() !== '/') {
        $location.path('/login');
    }
    return $q.reject(rejection);
}

然后我添加了以下内容:

app.run(['$rootScope', function ($rootScope) {
    $rootScope.$on('$locationChangeStart', function (evt, absNewUrl, absOldUrl) {
        $rootScope.previousPage = absOldUrl;
    });
}]);

然后我处理重定向后登录的代码如下所示:

var login = function (credentials) {
    return $http.post('/api/login', credentials).then(function (response) {
        var previousUrl = urlParserFilter($rootScope.previousPage);
        var path = previousUrl.hash.substr(1);
        if (path !== '/login') {
            $location.path(path);
        }
        else {
            $location.path('/');
        }
    });
};

遗憾的是,这仍然无法正确处理查询字符串,但它确实处理重定向,并且我将我的网站中包含查询字符串的唯一区域重新编写为不同的URL结构。我最终使用urlParser库来提供帮助。