Jquery ajax overwrite onreadystatechange handler

I have been tricked recently with some ajax polling methods. However, it seems I cannot overwrite the onreadystatechange handler from the XMLHttpRequest object in FireFox (3.6.7).

When tracking down the problem of why FF throws an exception when trying to access onreadystatechange , I realized that it depends on whether the send() method was called or not.

In other words, here is an example (plain js, without jQuery) that works:

(This is pretty simple to demonstrate)

 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, it’s better to say that you can access myxhr.onreadystatechange here. If I switch the last two lines of code, FF throws an exception, basically saying that I am not allowed access to this object.

 myxhr.send(null); console.log("onreadystatechange function: ", myxhr.onreadystatechange); 

Fails.

So where is my actual problem?

Well, I want to use jQuery $.ajax() . But if I try to overwrite the onreadystatechange method of the onreadystatechange object that was returned from $.ajax() , I get the same FireFox exception.

Ok, I already figured out why this is happening, so I thought, what about the beforeSend $.ajax() property? So I basically tried this:

 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 that FireFox throws an exception. So what are you doing right now? You digg into jQuery source like me. But in fact, it raised more questions than answers. It appears that beforeSend() actually called before xhr.send() executed. Therefore, I wonder why FireFox at this stage does not allow overwriting the handler.

Conclusion

Unable to create custom readystatechange handler using jQuery / Firefox?

+4
source share
3 answers

I agree with Maz here, you can still use query processing and object creation, and you don’t need to fix jquery for this

however, if you are not against jquery patches, you can add these lines

  // 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 do a search for readyState === 4 in the source

  // 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 $ .ajax again and place the handler for state2 and state3 as follows:

 $.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 just doesn't behave like other handlers, for example returngin false does nothing but you can still process the xhr object and abort this path.

bad look, can I imagine it to be included in the source later this day, who knows that they can accept it

+2
source

If you need a large level of customization, you can simply get the XMLHttpRequest object and control it yourself.

 var x=new $.ajaxSettings.xhr(); x.onreadystatechange=function(){ ... } ... 
+1
source

You can do this by doing something like this:

 $.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); }); }}); 
0
source

Source: https://habr.com/ru/post/1316546/


All Articles