覆盖XMLHttpRequest状态变量?

时间:2015-07-26 01:35:05

标签: javascript ajax xmlhttprequest monkeypatching

我正在开发一款可以在nw.js下或浏览器下工作的游戏引擎。在浏览器中,XMLHttpRequest为成功请求返回status = 200。但是,在nw.js中它返回0(因为加载本地文件时没有超时,呃)。

我的游戏引擎使用的外部库除了缩小之外,由于显而易见的原因,我自己(或我的游戏引擎的任何其他用户)都无法编辑。我的想法是覆盖" onreadystatechange"并且,如果我收到状态= 0,如果在nw.js下运行,则将其更改为status = 200。

我试过这个,但状态一直为零:

(function(xhr) {
    var send = xhr.send;
    xhr.send = function(data) {
        var rsc = this.onreadystatechange;
        if (rsc) {
            this.onreadystatechange = function() {
                if(this.readyState == 4)
                    if(this.status == 0)
                        this.status = 200;
                return rsc.apply(this, arguments);
            };
        }
        return send.apply(this, arguments);
    };
})(XMLHttpRequest.prototype);

这取自Rob W的优秀答案here。我还在MDN中读到状态变量是只读的。有没有办法覆盖它?在此先感谢:)。

1 个答案:

答案 0 :(得分:0)

我有类似的问题,当实际响应返回任何错误(任何大于300的代码)时,我不得不将状态代码更改为200。幸运的是,很好的回答for a similar question 让我知道如何更改状态代码。

(function() {
    var oldXMLHttpRequest = XMLHttpRequest;
    // define constructor for my proxy object
    XMLHttpRequest = function() {
        var actual = new oldXMLHttpRequest();
        var self = this;
        this.onreadystatechange = null;
        // this is the actual handler on the real XMLHttpRequest object
        actual.onreadystatechange = function() {
            self.status  = this.status;
            if (this.readyState == 4 ) {
                if (this.status >= 300) {
                    self.status = 200;
                } 
            }
            if (self.onreadystatechange) {
                return self.onreadystatechange();
            }
        };
        // add all proxy getters, except 'status'
        [ "statusText", "responseType", "response","responseText",
         "readyState", "responseXML", "upload"].forEach(function(item) {
            Object.defineProperty(self, item, {
                get: function() {return actual[item];}
            });
        });

        // add all proxy getters/setters
        ["ontimeout, timeout", "withCredentials", "onload", "onerror", "onprogress"].forEach(function(item) {
            Object.defineProperty(self, item, {
                get: function() {return actual[item];},
                set: function(val) {actual[item] = val;}
            });
        });

        // add all pure proxy pass-through methods
        ["addEventListener", "send", "open", "abort", "getAllResponseHeaders",
         "getResponseHeader", "overrideMimeType", "setRequestHeader"].forEach(function(item) {
            Object.defineProperty(self, item, {
                value: function() {return actual[item].apply(actual, arguments);}
            });
        });
    }
})();