jQuery 2.2打破了我的XHR重写

时间:2016-12-12 14:46:59

标签: javascript jquery ajax xmlhttprequest

我有一个相当简单的重写本地XMLHttpRequest对象,可以在2.2之前的所有版本的jQuery中正常工作。我试图弄清楚版本2.2中发生了什么变化。我查看了change log for version 2.2中的每一次提交,但找不到原因。

当从本机API发出AJAX请求时,它可以正常工作,当由$.ajax(来自jQ 2.2或更高版本)生成时,响应始终为undefined

这是一个工作小提琴:https://plnkr.co/edit/QADOKuxDvAhydrp46Bpk?p=preview

演示小提琴包括jQuery 2.2以及之前版本的jQuery中的对比评论。

这是我的XHR重写..

/**
 * XHR Rewrite
 * 
 * This file attempts to overwrite the XMLHttpRequest object so custom hooks can 
 * be added, although the current code does not add any hooks or do anything
 * special. This is just to test that the XHR function can successfully be 
 * overridden.
 */

// save the native XHR method to xhrConstructor;
var xhrType = XMLHttpRequest ? "XMLHttpRequest" : "ActiveXObject";
var xhrConstructor = window[xhrType];

// now override the native method
window[xhrType] = function(){
    console.log("xhr: constructor");

    this._xhr = new (Function.prototype.bind.apply(xhrConstructor, arguments));
    this.onreadystatechange = function(){};
    this.response = "";
    this.readyState = 0;
    this.responseText = "";
    this.responseType = 'text';
    this.responseURL = "";
    this.responseXML = null;
    this.status = 0;
    this.statusText = "";
    this.timeout = 0;
    this.withCredentials = false;

    var _this = this;
    this._xhr.onreadystatechange = function () {
        _this.getMockProperties();
        _this.onreadystatechange.apply(_this._xhr, arguments);
        _this.getMockProperties();
    };
};

window[xhrType].prototype.UNSENT = 0;
window[xhrType].prototype.OPENED = 1;
window[xhrType].prototype.HEADERS_RECEIVED = 2;
window[xhrType].prototype.LOADING = 3;
window[xhrType].prototype.DONE = 4;

window[xhrType].prototype.getMockProperties = function(){
    try{ this.response = this._xhr.response; }catch(e){}
    try{ this.readyState = this._xhr.readyState; }catch(e){}
    try{ this.responseText = this._xhr.responseText; }catch(e){}
    try{ this.responseURL = this._xhr.responseURL; }catch(e){}
    try{ this.responseXML = this._xhr.responseXML; }catch(e){}
    try{ this.status = this._xhr.status }catch(e){}
    try{ this.statusText = this._xhr.statusText; }catch(e){}
};

window[xhrType].prototype.setMockProperties = function(){
    try{ this._xhr.responseType = this.responseType; }catch(e){}
    try{ this._xhr.timeout = this.timeout; }catch(e){}
    try{ this._xhr.withCredentials = this.withCredentials; }catch(e){}
};

window[xhrType].prototype.abort = function(){
    console.log("xhr: abort");
    this.setMockProperties();
    var r = this._xhr.abort.apply(this._xhr, arguments);
    this.getMockProperties();
    return r;
};

window[xhrType].prototype.getAllResponseHeaders = function(){
    console.log("xhr: getAllResponseHeaders");
    this.setMockProperties();
    var r = this._xhr.getAllResponseHeaders.apply(this._xhr, arguments);
    this.getMockProperties();
    return r;
};

window[xhrType].prototype.getResponseHeader = function(){
    console.log("xhr: getResponseHeader");
    this.setMockProperties();
    var r = this._xhr.getResponseHeader.apply(this._xhr, arguments);
    this.getMockProperties();
    return r;
};

window[xhrType].prototype.overrideMimeType = function(){
    console.log("xhr: overrideMimeType");
    this.setMockProperties();
    var r = this._xhr.overrideMimeType.apply(this._xhr, arguments);
    this.getMockProperties();
    return r;
};

window[xhrType].prototype.setRequestHeader = function(){
    console.log("xhr: setRequestHeader");
    this.setMockProperties();
    var r = this._xhr.setRequestHeader.apply(this._xhr, arguments);
    this.getMockProperties();
    return r;
};

window[xhrType].prototype.send = function(){ 
    console.log("xhr: send");
    this.setMockProperties();
    var r = this._xhr.send.apply(this._xhr, arguments);
    this.getMockProperties();
    return r;
};

window[xhrType].prototype.open = function(){
    console.log("xhr: open");
    this.setMockProperties();
    var r = this._xhr.open.apply(this._xhr, arguments);
    this.getMockProperties();
    return r;
};

jQuery 2.2中的哪些内容破坏了我的代码?

1 个答案:

答案 0 :(得分:0)

从jQuery 2.2开始,他们使用content-type标头来确定响应的内容类型,而不是XMLHttpRequest.responseType。

完成的项目在这里,如果有人需要类似的东西:https://github.com/Pamblam/XHRCreep