重试 post/get 错误请求并完成原始 success/error 回调

Retry post/get requests on error and complete original success/error callbacks

我们有一个应用程序要求用户登录。用户登录后即可与网络交互 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 未设置为响应。无论如何我们可以重新运行任何失败的请求并继续执行吗?

你绝对是在正确的轨道上!您只需要进行一些小的更改即可确保结果返回到您的控制器:

$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);
        }
    };
});

查看 is 博客示例,其中他们正在做与您正在尝试做的相同的事情:http://www.webdeveasy.com/interceptors-in-angularjs-and-useful-examples/#sessionrecovererresponseerrorinterceptor