取消这样的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触发,该状态也用于超时或无网络连接。我希望能够区分拦截器中的两个场景
谢谢!
答案 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" });
});