从XMLHttpRequest send()捕获异步网络错误

Catch asynchronous network error from XMLHttpRequest send()

本文关键字:异步 网络 错误 XMLHttpRequest send      更新时间:2023-09-26

我正在使用XMLHttpRequest异步发送http请求:

xhr.open(method, uri, true);

当我发送something:

xhr.send(something)

当服务器关闭时,它抛出以下错误:

net::ERR_CONNECTION_REFUSED

如何捕获和处理这个错误?标准的try..catch块不工作,因为请求是异步的。

使用XMLHttpRequestonerror事件:

function aGet(url, cb) {
    var x = new XMLHttpRequest();
    x.onload = function(e) {
        cb(x.responseText)
    };
    x.onerror= function(e) {
        alert("Error fetching " + url);
    };
    x.open("GET", url, true);
    x.send();
}
var dmp = console.log.bind(console); // Dummy callback to dump to console
aGet("/", dmp) // Ok, uses onload to trigger callback
aGet("http://dgfgdf.com/sdfsdf", dmp); // Fails, uses onerror to trigger alert

我为这个问题写了一个完整的解决方案。它工作得很完美!
我有一个名为networkOrfail的函数,如果网络可用,它将尝试每秒重新发送XMLHttpRequest。否则,它将忽略请求。
当请求成功时,轮询停止并返回响应。

下面是检测网络是否可用的方法:
function getNavigatorConection() {
    return navigator.onLine;
}
然后创建XMLHttpRequest:
function makeRequest() {
    let xhr = new XMLHttpRequest();
    xhr.open('GET', 'anypage/anotherpage', true);
    xhr.timeout = 2000;
    xhr.onload = function () {
        // Your request is completed
        if (xhr.readyState == 4 && xhr.status == 200) {
            // You're in a successfully condition
        }
    };
    xhr.ontimeout = function (e) {
        // Your request timed out
    };
    xhr.send(null);
}

现在,按如下方式定义轮询方法:

function networkOrFail(callFunc, callTime) {
    let connected = getNavigatorConection();
    let callableTimes = callTime < 2000 ? 2000 : callTime;
    let toursBegin = 3;
    let tours = toursBegin;
    let intervalId;
    let request = function() {
        intervalId = setInterval(function() { 
        let connected = getNavigatorConection();
        if (tours > 0) {
            if (connected) {
                callFunc();
                tours =0;
                return false;
            }
            tours--;
            alert("i tryied againt to resend for another time and it remain just "+tours+" to retry");
        } else {
            clearRequest();
            tours =toursBegin;
        }
    }, callableTimes > 5000 ? 5000 : callableTimes);
    };
    let clearRequest = function() {
        clearInterval(intervalId);
        intervalId = null;
    };
    if (connected)
        callFunc();
    else
        request();
}

最后,通过轮询方法调用send方法,将其与超时(以分钟为单位)一起传递:

networkOrFail(makeRequest, 5000);