重试发布/获取请求并完成原始成功/错误回调

时间:2018-04-13 20:17:55

标签: angularjs http post get interceptor

我们有一个需要用户登录的应用程序。登录后,用户与web api进行交互。我们的问题是,当身份验证过期时,我们要显示一个登录页面,供用户重新定向时重新登录。这样他们就不会失去工作。我们的问题如下:

在我们的控制器内部发出请求

$http.get("/api/Document/GetDocumentsManage").success(function (response) {
       $scope.Documents = response;
});

在服务器上,我们确定用户不再经过身份验证,我们拒绝该呼叫。然后我们使用拦截器捕获错误并处理它以显示弹出模式。

$httpProvider.interceptors.push(function ($q, $injector) {

    return {
        'responseError': function (rejection) {

            var response = rejection;
            var defer = $q.defer();

            if (rejection.status == 401 || rejection.status == 400) {

                var modal = $injector.get("$mdDialog");
                modal.show({
                    parent: angular.element("body"),
                    targetEvent: window.event,
                    templateUrl: "/directives/LoginPage/Login.html",
                    controller: "loginController",
                    onRemoving: function () {

                        var $http = $injector.get("$http");
                        $http(rejection.config);
                    }
                });
            }

        }
    };
});

使用此代码,我们可以在用户导航离开页面的情况下成功重新进行身份验证,然后再次进行身份验证后,我们可以执行原始请求。我们的问题是重新提交的请求没有绑定到我们请求的原始.success回调。因此,在此示例中,$ scope.Documents未设置为响应。无论如何我们可以重新运行任何失败的请求并继续执行吗?

1 个答案:

答案 0 :(得分:0)

你肯定是在正确的轨道上!您只需要进行一些小的更改,以确保结果返回到您的控制器:

$httpProvider.interceptors.push(function ($q, $injector) {

    return {
        'responseError': function (rejection) {

            var response = rejection;
            var defer = $q.defer();
            var $http = $injector.get("$http");  //moved this for readability
            var modal = $injector.get("$mdDialog"); //moved this for readability

            if (rejection.status == 401 || rejection.status == 400) {

                modal.show({
                    parent: angular.element("body"),
                    targetEvent: window.event,
                    templateUrl: "/directives/LoginPage/Login.html",
                    controller: "loginController",
                    onRemoving: function () {
                        // resolve the deferred
                        deferred.resolve();
                    }
                });

                // return the promise object
                return deferred.promise.then(function() {
                  // return the new request promise
                  return $http(rejection.config);
                });
            }
            return $q.reject(rejection);
        }
    };
});

看一下博客示例,他们正在尝试做同样的事情:http://www.webdeveasy.com/interceptors-in-angularjs-and-useful-examples/#sessionrecovererresponseerrorinterceptor