javascript jQuery Ajax,覆盖 onreadystatechange 处理程序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3309185/
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
jQuery Ajax, overwrite onreadystatechange handler
提问by jAndy
I'm recently fooling around with some ajax polling techniques. However, it seems like I can't overwrite the onreadystatechangehandler from a XMLHttpRequestobject in FireFox (3.6.7).
我最近在玩弄一些 ajax 轮询技术。但是,似乎我无法onreadystatechange从XMLHttpRequestFireFox (3.6.7) 中的对象覆盖处理程序。
On tracking the problem why FF throws an exception when trying to access onreadystatechange, I realized it depends whether the send()method was called or not.
在跟踪为什么 FF 在尝试访问时抛出异常的问题时onreadystatechange,我意识到这取决于该send()方法是否被调用。
In other words, here is an example (plain js, no jQuery so far), that works:
换句话说,这是一个示例(纯 js,目前没有 jQuery),它有效:
(This is fairly simplified just for a demonstration)
(这只是为了演示而相当简化)
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);
This works, better said it's possible to access myxhr.onreadystatechangehere. If I switch the last two lines of code, FF throws an exception, basically telling me that I'm not allowed to access this object.
这有效,最好说可以在myxhr.onreadystatechange这里访问。如果我切换最后两行代码,FF会抛出异常,基本上是告诉我不允许访问此对象。
myxhr.send(null);
console.log("onreadystatechange function: ", myxhr.onreadystatechange);
Fails.
失败。
So where is my actual problem?
那么我的实际问题在哪里?
Well, I want to use jQuery's $.ajax(). But if I try to overwrite the onreadystatechangemethod of a XHRobject that was returned from $.ajax(), I receive the same FireFox exception.
好吧,我想使用 jQuery 的$.ajax(). 但是,如果我尝试覆盖从 返回onreadystatechange的XHR对象的方法,则会$.ajax()收到相同的 FireFox 异常。
Ok I already found out why this happens, so I thought about, hey what about the beforeSendproperty of $.ajax()? So I basically tried this:
好的,我已经找到了为什么会发生这种情况,所以我想,嘿, 的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);
}
});
Guess what, FireFox throws an exception. So what do you do now? You digg into the jQuery source, like I did. But that brought more questions than answers actually. It looks like beforeSend()is really called before xhr.send()is executed. So I'm wondering why on earth FireFox does not allow to overwrite the handler at this point.
猜猜看,FireFox 抛出异常。那你现在怎么办?您像我一样深入研究 jQuery 源代码。但这实际上带来的问题多于答案。看起来beforeSend()在xhr.send()执行之前真的被调用了。所以我想知道为什么 FireFox 在这一点上不允许覆盖处理程序。
Conclusion?
结论?
It's impossible to create a custom readystatechange handlerwith jQuery/Firefox ?
custom readystatechange handler用 jQuery/Firefox创建一个是不可能的?
采纳答案by Paul Scheltema
I agree with Maz here, you can still benefit form the query handling and creating of the object, and also no need to patch jquery for this
我在这里同意 Maz 的观点,您仍然可以从查询处理和对象的创建中受益,而且无需为此修补 jquery
however, if you dont mind patching jquery you could add these lines
但是,如果您不介意修补 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 );
before this line: (jQuery v 1.4.4) or just search for the readyState === 4 in the source
在这一行之前:(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") ) {
now you can use the $.ajax again and put a handler up for state2 and state3 like so:
现在您可以再次使用 $.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');}
});
it doesnt exactly behave like the other handlers, eg returngin false wont do a thing but you can still handle the xhr object and abort that way
它的行为与其他处理程序完全不同,例如 returngin false 不会做任何事情,但您仍然可以处理 xhr 对象并以这种方式中止
ill see if i can submit this to be included in the source later this day, who knows they might accept it
我看看我是否可以在今天晚些时候提交这个以包含在来源中,谁知道他们可能会接受它
回答by Maz
If you want a large level of customization, you can just get the XMLHttpRequest object and control it yourself.
如果您想要大量的自定义,您可以只获取 XMLHttpRequest 对象并自己控制它。
var x=new $.ajaxSettings.xhr();
x.onreadystatechange=function(){ ... }
...
回答by Vinicius
You can do this by doing something like that:
你可以通过做这样的事情来做到这一点:
$.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); });
}});

