我最近在讨论一些ajax轮询技术。但是,我似乎无法覆盖FireFox(3.6.7)中onreadystatechange
对象的XMLHttpRequest
处理程序。
在跟踪问题时,为什么FF在尝试访问onreadystatechange
时抛出异常,我意识到这取决于是否调用了send()
方法。
换句话说,这是一个例子(普通的js,到目前为止没有jQuery),它有效:
(这只是为了演示而相当简化)
var myxhr = new XMLHttpRequest();
myxhr.open("GET", "/my/index.php");
myxhr.onreadystatechange = function(){
console.log('ready state changed');
};
console.log("onreadystatechange function: ", myxhr.onreadystatechange);
myxhr.send(null);
这有效,更好地说可以在这里访问myxhr.onreadystatechange
。如果我切换最后两行代码,FF会抛出一个异常,基本上告诉我我不允许访问这个对象。
myxhr.send(null);
console.log("onreadystatechange function: ", myxhr.onreadystatechange);
失败。
那我的实际问题在哪里?
好吧,我想使用jQuery的$.ajax()
。但是,如果我尝试覆盖从onreadystatechange
返回的XHR
对象的$.ajax()
方法,则会收到相同的FireFox异常。
好的,我已经找到了为什么会发生这种情况,所以我想到了,嘿beforeSend
$.ajax()
属性怎么样?所以我基本上试过这个:
var myxhr = $.ajax({
url: "/my/index.php",
type: "GET",
dataType: "text",
data: {
foo: "1"
},
beforeSend: function(xhr){
var readystatehook = xhr.onreadystatechange;
xhr.onreadystatechange = function(){
readystatehook.apply(this, []);
console.log('fired');
};
},
success: function(data){
console.log(data);
},
error: function(xhr, textStatus, error){
console.log(xhr.statusText, textStatus, error);
}
});
猜猜看,FireFox会抛出异常。那你现在做什么?你像我一样深入研究jQuery源代码。但实际上,这带来的问题多于答案。看起来beforeSend()
在执行xhr.send()
之前就已经被调用了。所以我想知道为什么FireFox在此时不允许覆盖处理程序。
结论
用jQuery / Firefox创建custom readystatechange handler
是不可能的吗?
答案 0 :(得分:2)
我同意Maz在这里,你仍然可以从查询处理和创建对象中受益,也不需要为此修补jquery
但是,如果您不介意修补jquery,可以添加这些行
// The readystate 2
} else if ( !requestDone && xhr && xhr.readyState === 2 && isTimeout !== 'timeout' && s.state2) {
s.state2.call( s.context, data, status, xhr );
// The readystate 3
} else if ( !requestDone && xhr && xhr.readyState === 3 && isTimeout !== 'timeout' && s.state3) {
s.state3.call( s.context, data, status, xhr );
在这一行之前:(jQuery v 1.4.4)或者只是在源中搜索readyState === 4
// The transfer is complete and the data is available, or the request timed out
} else if ( !requestDone && xhr && (xhr.readyState === 4 || isTimeout === "timeout") ) {
现在你可以再次使用$ .ajax并为state2和state3设置一个处理程序,如下所示:
$.ajax({
url: 'http://www.stackoverflow.com',
cache: false,
success:function(){console.log('success');},
error: function (){console.log('error');},
complete: function (){console.log('complete');},
state2: function (context,data,status,xhr) {console.log('state2');},
state3: function (context,data,status,xhr) {console.log('state3');}
});
它并不像其他处理程序那样完全表现,例如,returnngin false不会做任何事情 但你仍然可以处理xhr对象并以此方式中止
看看我是否可以在今天晚些时候将其提交到源代码中,谁知道他们可能会接受它
答案 1 :(得分:1)
如果您需要大量的自定义,您可以获取XMLHttpRequest对象并自行控制它。
var x=new $.ajaxSettings.xhr();
x.onreadystatechange=function(){ ... }
...
答案 2 :(得分:-1)
你可以通过这样做来做到这一点:
$.ajax({
type: "POST",
url: "Test.ashx",
data: { "command": "test" },
contentType: "application/x-www-form-urlencoded; charset=utf-8",
dataType: "json",
beforeSend: function (request, settings) {
$(request).bind("readystatechange", function (e) { alert("changed " + e.target.readyState); });
}});