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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25395119/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 04:27:45  来源:igfitidea点击:

Catch asynchronous network error from XMLHttpRequest send()

javascripthtmlhttpxmlhttprequest

提问by rustybeanstalk

I'm making an http request asynchronously using XMLHttpRequest:

我正在使用XMLHttpRequest以下方式异步发出 http 请求:

xhr.open(method, uri, true);

When I send something:

当我发送something

xhr.send(something)

When the server is down, it throws the following error:

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

net::ERR_CONNECTION_REFUSED

How can I catch and handle this error? The standard try..catchblock doesn't work as the request is asynchronous.

我怎样才能捕捉和处理这个错误?标准try..catch块不起作用,因为请求是异步的。

Thanks in advance.

提前致谢。

回答by dandavis

Use the onerrorevent of the XMLHttpRequest:

使用以下onerror事件XMLHttpRequest

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

回答by Ir Calif

I wrote a full solution to that problem. It works perfectly!
I have a function called networkOrfailwhich will try to resend the XMLHttpRequesteach second, if the network is available. Otherwise, it'll ignore the request.
When the request is succeeded, that polling stops and the response is returned.

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

Here's how to detect whether the network is available:

下面是如何检测网络是否可用:

function getNavigatorConection() {
    return navigator.onLine;
}

Then, create your XMLHttpRequest:

然后,创建您的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);
}

Now, define your polling method as follows:

现在,定义您的轮询方法如下:

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();
}

Finally, call the send method through the polling method by passing it toghether with the timeout in minutes:

最后,通过轮询方法调用 send 方法,方法是将它与以分钟为单位的超时时间一起传递:

networkOrFail(makeRequest, 5000);