$http错误处理:区分用户离线和其他错误

2024-02-03

我有一个简单的联系表单,Angular 通过 AJAX 将其提交到我在 Google App Engine 上的应用程序。 (POST 处理程序使用发送邮件 https://cloud.google.com/appengine/docs/python/mail/sendingmail向网站所有者发送电子邮件的功能)。这是客户端代码:

$http.post('', jQuery.param(user), {
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
    }
}).success(function(data, status, headers, config) {
    //...                        
}).error(function(data, status, headers, config) {
    alert('Please check your Internet connection and try again.');
});

显然alert()正在处理所有错误。假设我的服务器端代码中没有错误,我猜测 App Engine 返回除 HTTP 状态代码 200 之外的任何内容的可能性很低。但是我仍然想区分服务器错误和用户失去连接。

我正在考虑使用 XMLHttpRequesttextStatus as per 这个答案 https://stackoverflow.com/a/992716/1898641,但它似乎不适用于$http.error()打回来。我也想过使用离线.js http://github.hubspot.com/offline/docs/welcome/但我不需要它所做的大部分功能,因此在这种情况下这看起来像是浪费字节。

The $http.error() status当离线为 0 时,我得到了,但我不确定跨浏览器的可靠性如何。我应该使用什么?


在为您提供解决方案之前,我只想强调一下浏览器提供的 is-offline 标志的问题

  1. 不同浏览器的离线标志有不同的含义

    A。对于某些浏览器,这意味着互联网不存在

    b.对于某些浏览器,这意味着 Intranet 不存在

    C。有些浏览器确实允许离线模式,因此即使没有互联网,您实际上也没有离线。

  2. 并非所有浏览器都以一致的方式支持离线

我使用基于浏览器的标志时遇到的另一个问题是开发场景,其中不需要互联网,并且不应触发离线模式(对我来说,如果我的网站离线,我会阻止所有用户交互)。您可以通过使用另一个指示器来告诉您是否处于开发/生产等状态来解决此问题。

最重要的是,为什么我们关心浏览器是否处于离线模式,是因为我们只关心我们的网站是否可以访问,我们实际上并不关心互联网是否存在。因此,即使浏览器告诉我们它处于离线状态,这也不是我们想要的。我们想要的和浏览器提供的之间存在微小的差异。

因此,考虑到上述所有内容,我已经使用离线指令解决了问题,如果用户离线,我将使用该指令来阻止用户交互

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 true/false 中的逻辑替换为您想要的任何自定义逻辑。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

$http错误处理:区分用户离线和其他错误 的相关文章

随机推荐