前端之家收集整理的这篇文章主要介绍了
ajax – $http错误处理:区分用户脱机与其他错误,
前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
@H_
301_0@
我有一个简单的联系表单,Angular通过
AJAX提交到我在Google App Engine上的应用程序. (POST处理程序使用
send_mail函数向网站所有者发送电子
邮件).这是客户端
代码:
$http.post('',jQuery.param(user),{
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}).success(function(data,status,headers,config) {
//...
}).error(function(data,config) {
alert('Please check your Internet connection and try again.');
});
显然,alert()正在处理所有错误.假设我的服务器端代码没有错误,我猜测App Engine返回除HTTP状态代码200以外的任何其他内容的可能性很低.但是,我仍然希望区分服务器错误和丢失连接的用户.
我正在考虑按照this SO answer使用XMLHttpRequest的textStatus,但它似乎不能用于$http.error()回调.我还想过使用Offline.js,但我不需要它做的大部分工作,因此在这种情况下看起来像浪费的字节.
离线时获得的$http.error()状态为0,但我不确定跨浏览器的可靠性如何.我该怎么用?
在给出
解决方案之前,我只是想强调浏览器提供的is-offline标志的问题
>不同浏览器的离线标志有不同的结合
一个.对于某些浏览器,它意味着互联网不存在
湾对于某些浏览器,它意味着内部网不存在
C.有些浏览器确实允许离线模式,所以即使没有互联网,你也不会实际离线.
>并非所有浏览器都以一致的方式支持离线
我使用基于浏览器的标志的另一个问题是开发场景,其中不需要互联网,并且不应该触发离线模式(对我来说,我阻止所有用户交互如果我的网站脱机).您可以通过另一个指示器告诉您是否处于dev / prod等来解决此问题.
最重要的是,为什么我们要关心浏览器是否处于离线模式,因为我们只关心我们的网站是否可以访问,我们实际上并不关心互联网是否存在.因此,即使浏览器告诉我们它处于脱机状态,它也不是我们想要的.我们想要的东西与浏览器提供的东西之间存在细微差别.
所以考虑到上述所有情况,我已经使用离线指令解决了这个问题,我用它来阻止用户离线时的用户交互
csapp.directive('csOffline',["$http",'$interval',"$timeout","$modal",function ($http,$interval,$timeout,$modal) {
var linkFn = function (scope) {
scope.interval = 10; //seconds
var checkConnection = function () {
$http({
method: 'HEAD',url: document.location.pathname + "?rand=" + Math.floor((1 + Math.random()) * 0x10000)
})
.then(function (response) {
$scope.isOnline = true;
}).catch(function () {
$scope.isOnline = false;
});
};
scope.isOnline = true;
$interval(checkConnection,scope.interval * 1000);
scope.$watch('isOnline',function (newVal) {
console.log("isOnline: ",newVal);
//custom logic here
});
};
return {
scope: {},restrict: 'E',link: linkFn,};
}]);
我准备使用offline.js,它太多了,而且大多数我都不需要,所以这就是我提出的解决方案,纯粹是在angular.js中.
请注意在这些调用期间调用http拦截器,我想避免这种情况,因此我使用$.ajax进行调用
$.ajax({
type: "HEAD",url: document.location.pathname + "?rand=" + Math.floor((1 + Math.random()) * 0x10000),contentType: "application/json",error: function () {
scope.isOnline = false;
},success: function (data,textStatus,xhr) {
var status = xhr.status;
scope.isOnline = status >= 200 && status < 300 || status === 304;
}
}
);
你可以用你想要的任何自定义逻辑替换isOnline中的逻辑真/假.