ajax – $http错误处理:区分用户脱机与其他错误

前端之家收集整理的这篇文章主要介绍了ajax – $http错误处理:区分用户脱机与其他错误前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个简单的联系表单,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中的逻辑真/假.

猜你在找的Ajax相关文章