Skip to main content

Bug Tracker

Side navigation

#3858 closed bug (wontfix)

Opened January 15, 2009 04:29AM UTC

Closed January 19, 2009 09:17PM UTC

Last modified March 14, 2012 10:57PM UTC

weird jQuery 1.3 ajax difference in behavior

Reported by: shadedecho Owned by: flesler
Priority: major Milestone: 1.3.1
Component: ajax Version: 1.3
Keywords: ajax flxhr Cc:
Blocked by: Blocking:
Description

First, let me say a big congrats to all the jQuery devs for their excellent work on jQuery 1.3 (and happy third birthday!). I'm very excited about this release.

I've noticed a problem with some of my jQuery ajax code when going from 1.2.6 to 1.3. I've got two URL's which demonstrate the different behavior.

Moreover, the difference in behavior seems to be related to what domain is in the address bar. So, to test and demonstrate this, I've set it up so the following URL's can be visited each with two different domains, so you can see the different behavior just based on the browser address bar domain (page-domain).

These examples exploit substituting in flXHR (http://flxhr.flensed.com/) as a replacement XHR object (means it speaks the same API), and so it shouldn't be a problem with it speaking that API wrongly or not being adapted properly.

http://www.flensed.com/code/dev-tests/flxhr-jquery-126.html (1.2.6-patched, works)

http://flxhr.flensed.com/code/dev-tests/flxhr-jquery-126.html (1.2.6-patched, works)

http://www.flensed.com/code/dev-tests/flxhr-jquery-13.html (1.3, works)

http://flxhr.flensed.com/code/dev-tests/flxhr-jquery-13.html (1.3, fails! the request fails silently and never finishes).

Now, I know that the temptation will be to say this is something with flXHR misbehaving (what I assumed at first), but consider that all 4 URL's above use the exact same version of flXHR (and everything else), and the only thing that changes from success and causes the failure between the 2nd URL (which works) and the 4th URL (which fails) is jQuery 1.2.6 versus 1.3. Also, notice that the 3rd URL works with jQuery 1.3.

The failure, as I've tracked it so far, is that a request seems to get sent off exactly the same as in the working examples, but the request only gets to state 3, and never finishes. This is as far as I've been able to diagnose so far.

Does anyone have any idea what might have changed with 1.3 that would be causing this weird never-finishing request behavior? Can anyone help me figure it out?

Attachments (0)
Change History (5)

Changed January 15, 2009 01:37PM UTC by john comment:1

milestone: 1.31.3.1
owner: → ariel
version: → 1.3

Ariel - any thoughts here?

Changed January 16, 2009 07:43AM UTC by shadedecho comment:2

OK, I have an update from some further testing on this topic.

Contrary to my conjecture originally, I have confirmed that in both cases, flXHR fully returns (that is, gets to readyState=4), with the responseText set as expected.

However, what I've determined is that jQuery has already "aborted" and given up on the request. The tricky part is why -- the reason is that sometimes flXHR doesn't immediately go from readyState 0 to 1 when open() is called -- whenever there is an additional cross-domain policy check that needs to first be performed (which is what happens when the URL's are different, as in my original post). So, basically, there's a race condition created, and jQuery now has logic in it which gets tripped up on this race condition.

The triggering jQuery code difference that causes this "bug" to show up from 1.2.6 to 1.3 is that you now have this bit of code in there:

if (ival) {
	// clear poll interval
	clearInterval(ival);
	ival = null;
	// Handle the global AJAX counter
	if ( s.global && ! --jQuery.active )
		jQuery.event.trigger( "ajaxStop" );
}

Basically, this check gets called quickly enough (after the first 13ms interval wait) that flXHR hasn't yet moved from 0 to 1. So, jQuery thinks the operation has somehow been aborted and so it abandons the request (even though flXHR is still going just fine in the background).


So, bottom line, there is a technical reason why I have flXHR not moving to readyState=1 until the policy check is made (which I can explain if you are interested), but basically it creates now an incompatibility with jQuery's new logic relating to how it tries to determine if an XHR request should be abandoned because it was aborted.

Firstly, I will retract my previous assertion this is purely a jQuery bug. Clearly it's not a "bug" but just an incompatibility between flXHR's implementation of 'XHR' and jQuery's interpretation/recognition of how the native browser XHR works.

So, this all having been diagnosed, I will ask this for your consideration on how (and if) to proceed... Is jQuery's logic as described here fully appropriate (basically to assume a '0' at this point in code logic is absolutely a sign of an aborted request)?

Or is it possible that alternate logic could be suggested, which would continue to work exactly the same for normal jQuery usage, but would alleviate this hitch with flXHR?

I have two suggestions along those lines:

1. Use some other logic to detect an aborted XHR request, not just readyState=0 after open() was called.

2. Don't start the looping "listening" interval immediately after open() as it does now, but start it only after the XHR object has moved out of the '0' state for the first time.

This '0-to-1' state change could easily be detected by initially attaching an 'onreadystatechange' handler to look for a movement out of the '0' state, at which point the handler/listener could be unassigned and THEN the interval looping logic would kick in.

Not only would this resolve the issue with flXHR... but, I would submit for your consideration that it's possibly a slightly more robust logic to use for this test. In other words, it's conceivable that there are other reasons why some browser's XHR object's open() command might not move the object immediately into the '1' state -- for instance, some internal code execution delay in some browser implementation (like activeX).

It would seem (to me at least) to make a little more sense not to start looping and listening for changes until you know the object has in fact moved to the '1' state fully, and is now clearly in the process of sending/receiving data.

Changed January 17, 2009 10:20PM UTC by john comment:3

owner: arielflesler

Changed January 19, 2009 02:59PM UTC by shadedecho comment:4

I did a patch release for flXHR (1.0.2, http://flxhr.flensed.com/download.php) which now forces it to maintain a 'readyState' transition process which mimics more closely the internal native XHR, in that it moves the readyState immediately from 0 to 1, even if internally things are still waiting. This resolves the race condition (for now) between flXHR and jQuery.

However, for posterity sake, I would still renew my question/request that perhaps this logic be reworked a little bit for the next release, given my reasons above. Thanks.

Changed January 19, 2009 09:17PM UTC by john comment:5

resolution: → wontfix
status: newclosed

Thanks for all your comments and thoughts on this issue. At least for now, I think we're going to have to leave the code as-is. Doing the abort check with readyState === 0 is best that we've found, so far, so I think we'd like to stick with it. On the plus side, it means that your code is that much closer to the "real deal" now :-)

If an alternative solution could be found, at some point, we can definitely re-open and re-examine the issue.