angular-js:为已取消的请求设置HTTP状态代码

时间:2015-03-30 21:48:25

标签: angularjs http

取消这样的http请求时:

$scope.runTest = function() {
    if (canceler) canceler.resolve();
    canceler = $q.defer();
    $http({
        method: 'GET',
        url: 'http://www.google.com/',
        timeout: canceler.promise
    })
    .success(function(data) {
        $scope.result.push({msg: "this won't be displayed on cancel"});
    })
    .error(function(data) {
        $scope.result.push({msg: "this will be displayed on cancel"});
    });
};

是否可以使取消的HTTP请求具有特定的HTTP代码,例如205?它会导致http拦截器以http状态0触发,该状态也用于超时或无网络连接。我希望能够区分拦截器中的两个场景

谢谢!

2 个答案:

答案 0 :(得分:7)

我最终采用了以下方法:

$scope.runTest = function() {

    if (canceler) {
        // Set non-zero status for http interceptors
        // Using 499, an nginx extension to flag cancelled http requests
        // Could be something else like a boolean, using status code for convenience
        canceler.promise.status = 499;

        // Cancel the request
        canceler.resolve();
    }

    canceler = $q.defer();
    $http({
        method: 'GET',
        url: 'http://www.google.com/',
        timeout: canceler.promise
    })
    .success(function(data) {
        // On sucesss
    })
    .error(function(data) {
        // On error
    });
};

这里我只是在超时时设置了一些内容,将请求标记为已取消,正如@Daniel Silva建议的那样。然后在我的http拦截器上:

app.config(function($httpProvider) {

    $httpProvider.interceptors.push(function($q) {
        return {
            'responseError': function(response) {

                var statusCode = response.status;

                // Get status from timeout, if 0 and timeout present
                if (statusCode === 0 && response.config.timeout) {
                    statusCode = response.config.timeout.status;
                }

                // Ignore client request cancelled
                if (statusCode === 499) {
                    return response;
                }

                // Reject via $q, otherwise the error will pass as success
                return $q.reject(response);
            }
        };
    });
});

答案 1 :(得分:1)

你需要记住,Angular $ http超时是一个“客户端”超时,尽管它与服务器超时的名称相同。 配置angular $ http timeout时,你会说“我不会等到服务器超时”。这在访问第三方API时特别有用,因为您无法配置超时设置。

这是http状态为0的原因。没有http 408响应,因为Angular取消请求而不是等待服务器超时。

您可以使用$ timeout service返回的承诺来处理客户端超时

var myTimeout = $timeout(function () {
    console.log("Cannot wait you anymore!");
}, 1000); 

$http({
    method: 'GET',
    url: 'http://www.google.com/',
    timeout: myTimeout
})
.success(function (data) {
    $scope.result.push({ msg: "this won't be displayed on cancel" });
})
.error(function (data) {
    $scope.result.push({ msg: "this will be displayed on cancel" });
});