如何为XMLHttpRequest设置超时和ontimeout?

时间:2016-06-27 09:15:15

标签: javascript ajax

目前,我正在使用下面显示的类似代码,在创建timeout的实例时为XMLHttpRequest设置特定值。 我还为ontimeout设置了一个函数,该函数将在事件被触发时执行。

我想知道在调用timeout时是否可以为任何XMLHttpRequest和全局函数全局设置ontimeout值。

我知道我可以使用XMLHttpRequest的工厂,可以在创建的每个实例上自动设置timeoutontimeout,但我想知道是否存在不同的方法。

注意:我正在寻找基于vanilla JavaScript(没有jQuery或其他库)的解决方案,我只针对Chrome和FireFox最新版本。

欢迎任何想法,谢谢。

var xhr = new XMLHttpRequest();
xhr.open('GET', '/server', true);
xhr.timeout = 2000;  
xhr.onload = function () {};   
xhr.ontimeout = function (e) {
    // do smt here
}; 
xhr.send(null);

2 个答案:

答案 0 :(得分:2)

您至少有三个选择:

  1. 在您自己的函数中封装XMLHttpRequest的使用。这允许您在该函数中应用这些类型的东西。您的代码使用该功能的事实使得它非常清楚发生了什么。例如:

    function createXHR() {
        var xhr = new XMLHttpRequest();
        xhr.timeout = 2000;  
        xhr.addEventListener("timeout", function(e) {
            // ...
        });
        return xhr;
    }
    
  2. 使用您自己的版本覆盖XMLHttpRequest我不建议这样做,但有时如果您需要直接与使用XMLHttpRequest的代码集成,您可能会觉得需要这样做。例如:

    (function() {
        var realXMLHttpRequest = XMLHttpRequest;
        XMLHttpRequest = function fakeXMLHttpRequest() {
            realXMLHttpRequest.apply(this, arguments);
            this.timeout = 2000;  
            this.addEventListener("timeout", function(e) {
                // ...
            });
        };
        XMLHttpRequest.prototype = realXMLHttpRequest.prototype;
    })();
    

    同样,我不推荐,但这是可能的。

    您在下面说过,上面的内容对您不起作用。如果没有,那是因为你正在使用的XMLHttpRequest实现让生活变得困难。此解决方法将起作用:

    (function() {
        var realXMLHttpRequest = XMLHttpRequest;
        XMLHttpRequest = function fakeXMLHttpRequest(arg) {
            var xhr;
            if (typeof arg !== "undefined") {
                // Some implementations allow for a non-standard argument, support them
                xhr = new realXMLHttpRequest(arg);
            } else {
                // Normal case
                xhr = new realXMLHttpRequest();
            }
            xhr.timeout = 2000;  
            xhr.addEventListener("timeout", function(e) {
                // ...
            });
            return xhr;
        };
        XMLHttpRequest.prototype = realXMLHttpRequest.prototype;
    })();
    

    即使你用new XMLHttpRequest调用它也行得正常,因为new运算符的工作方式是它创建一个对象并使用该对象调用该函数为this,然后new的结果是该对象,除非该函数返回一个不同的非null对象,如上所述。

    我提到我不推荐这个? ; - )

  3. 使用已经为您做过#1的库。

答案 1 :(得分:0)

我能够使用以下代码来路径XMLHttpRequest

  (function (xhr) {
        var send = xhr.send;
        xhr.send = function (data) {
            this.timeout = 5000;
            var hasTimeOut = 'ontimeout' in this;
            if (hasTimeOut) {
                this.ontimeout = function () {
                    throw ('Error XMLHttpRequest timeout.');
                };
            }
            return send.apply(this, arguments);
        };
    })(XMLHttpRequest.prototype);