Welcome to WebmasterWorld Guest from

Forum Moderators: open

Message Too Old, No Replies

A Night at the Opera, with a Firefox, while on Safari

A Few Notes on How Browsers Behave Differently in AJAX

8:12 pm on Dec 20, 2006 (gmt 0)

Senior Member

WebmasterWorld Senior Member 10+ Year Member

joined:Feb 21, 2005
votes: 0

I just finished the first revision of an AJAX threading handler.

In any case, I test with a number of browsers. The tool I developed produces a log that shows which callbacks are being sent when, and it revealed some interesting results that highlighted some browser differences.

First, a bit of background:
The XMLHTTPRequest Object [w3.org] is a JavaScript "facade" over the basic HTTP Request [w3.org] and HTTP Response [w3.org]. It encapsulates them into a single object and greatly reduces the underlying complexity.

These two actions form the underpinnings of the Web. Almost every action on a Web site is dictated by these.

Basically, the way it works is thus:

First, a browser initiates a HTTP Request [w3.org]. This can be done via GET or POST. In GET, the URL is complete with all data. In POST, it is sent separately. There's actually a heck of a lot more that can (and will) go on here, but, for the purposes of AJAX, the basic GET and POST is pretty much what we concern ourselves with.

After the browser makes its HTTP Request [w3.org], the server responds with a HTTP Response [w3.org].

This is all hidden inside the object, so you only see four different statuses, along with some data. For my purposes, I only look at the responseText [w3.org] data member, which has the actual text spit up by the server. There are a number of other fields which can be quite useful, but I try to keep things simple.

There is another data member, readyState [w3.org], which contains a simplified summary of the response state. There are four possible values for this:

0 Uninitialized

1 Open

2 Sent

3 Receiving

4 Loaded

Read the W3C Page [w3.org] to find out more about these.

What it boils down to, is that:

0 Is pretty much useless.
1 Just means that the browser is getting ready to send it.
2 Means that it sent it, but no guarantees the server is ready to digest it yet.
3 Means the server has got it and is gonna get back to us.
4 Means the server is done with the request, and washes its hands of it.

In my testing, 3 and 4 always happened at the same time. I didn't get 3 until the server was done processing, and 4 immediately followed 3.

Here's what my testing turned up. I tested the following browsers on Mac OS (I'm a Mac person):

Firefox 2 [en-us.www.mozilla.com] (with the WebDeveloper Extension [chrispederick.com])
Apple Safari [apple.com] (10.4.8 Version)
Opera 8.02
Opera 9.1 [opera.com]
iCab 3.01 [icab.de] (This is an excellent testing browser)

On Windows, I tested with:

Firefox 2
Microsoft Internet Explorer 6
Microsoft Internet Explorer 7
Opera 9.1

My tests consisted of using a testbed that allows threaded, simultaneous requests, or queued, sequential requests. These tests were done with both.

With the testbed version, I have a method of triggering 144 requests, one right after the next, so they are virtually simultaneous. The queued version will hold one request until the previous one has completed. I have it set up so that each URL is different. This has a real effect on the way the browsers behave. The test consists of calling a simple PHP file that executes a 2-second delay before spitting out a bit of text.

Here's what I noted:

Basically, the same browser supported on both platforms (Firefox and Opera) behaved exactly the same, regardless of the platform.

Response Stages:

In Firefox, you get an immediate Stage 1 callback, and a Stage 2 callback almost immediately after that.

In Opera, you don't get any callbacks at all until Stage 3.

In iCab, you don't get the Stage 1 callback, but you do get an immediate Stage 2 callback.

In IE, Safari and iCab, you won't get any response text until Stage 4.

In Safari, you don't get a response until Stage 2, and that is not immediate (iCab is immediate).

In none of the browsers did I get a Stage 0 callback.

The lesson here is that you can't depend on squat until Stage 3, and you can't use response text until Stage 4.


Firefox seems to have an internal queue, and the requests execute fairly sequentially. Stage 1 is reached immediately for all requests, but Stage 2, 3 and 4 come in directly sequentially for each request. There is a bit of mixing. It looks like it does two connections at a time, and executes the second of the pair first.

Various browsers had varying numbers of connections that executed sequentially. Firefox seems to do two at a time. Opera seems to do 8 at a time.

Opera 8 was completely sequential. There was no "mixing" of the requests. Opera 9 was all over the place.

Apple Safari seemed to be the fastest to finish all 144 requests.

Opera 8 and 9 seemed to give back the most control to the user. Firefox and iCab were the worst "control freaks."

iCab locked up on the "full bore" test. I couldn't complete this test, and force-quit the app after about ten minutes.

Opera has a rather annoying bug. This occurred in both 8 and 9: If the URL is exactly the same, the PHP file results are cached, and all the requests terminate as soon as the first result is returned. IE does the same, but I was able to fix it by spitting out a couple of "no-cache" headers. Opera ignores these headers.

I fixed that by adding an "id=" parameter to the URL, which made each URL unique. This forced Opera to stop caching.

This is just what I found from my rather informal testing. The results seemed interesting enough to share.

[edited by: DrDoc at 6:42 pm (utc) on Dec. 21, 2006]
[edit reason] JS Forum Charter [WebmasterWorld.com] [/edit]

5:19 pm on Dec 21, 2006 (gmt 0)

Senior Member

WebmasterWorld Senior Member drdoc is a WebmasterWorld Top Contributor of All Time 10+ Year Member

joined:Mar 15, 2002
votes: 0

That is indeed interesting! Certainly useful information for anyone dabbling with AJAX and in need of monitoring multiple requests and such.

Thanks for sharing.

5:17 pm on Dec 22, 2006 (gmt 0)

Full Member

10+ Year Member

joined:Aug 8, 2003
posts: 232
votes: 0

This is great information. One thing that I have noticed is that with IE the responses are cached when using a GET method in the HTTP request. If you use POST then the responses are not cached. It sounds like adding the no-cache headers fixes the problem too. I have not tested GET vs. POST with Opera but it might be worth a shot.
6:33 pm on Dec 22, 2006 (gmt 0)

Senior Member

WebmasterWorld Senior Member 10+ Year Member

joined:Apr 20, 2004
votes: 0

Thanks a lot! Good notes ...
you can't use response text until Stage 4
because there is no response text until the server tries to handle the request, unless you count ACKs as a response.

I, too have noted the caching issue with IE(6), however I haven't been able to get it to recognize a no-cache header when using dynamic content. i.e. call to the same PHP file with different parameters. Is there anything other than no-cache headers that worked, for you?

7:53 pm on Dec 22, 2006 (gmt 0)

Senior Member

WebmasterWorld Senior Member 10+ Year Member

joined:Feb 21, 2005
votes: 0

Firefox actually gives you full response data in Step 3, and every browser except IE lets you at least peek at responseText before 4. IE throws a nutty if you try it.

Here's the complete text of my little PHP file:

header ( "Pragma: no-cache" );
header ( "Cache-Control: no-cache" );

$delay = $_POST['delay'];

if (!$delay )
$delay = $_GET['delay'];

$id = $_POST['id'];

if (!$id )
$id = $_GET['id'];

$t = (time() + (abs ( $delay )));
while ( time() <= $t ) {};// Real, REAL basic delay

if ( $id )
echo "(ID: $id) ";

echo "The request took $delay seconds to execute on the server.";
9:48 pm on Dec 22, 2006 (gmt 0)

Senior Member

WebmasterWorld Senior Member 10+ Year Member

joined:Feb 21, 2005
posts: 1526
votes: 0

Just as an addendum to this. I upgraded my iCab browser to 3.0.1, and now it throws an odd JavaScript error that says that my main AJAX function doesn't exist. I'll investigate more when I get a chance. I don't lose too much sleep over iCab, but it is a truly excellent testing browser. I use it for testing stuff that has dynamic content and secure access.
9:49 pm on Dec 22, 2006 (gmt 0)

Senior Member

WebmasterWorld Senior Member 10+ Year Member

joined:Feb 13, 2005
votes: 0

Use this to get rid of any caching issues:

obj.setRequestHeader('If-Modified-Since', 'Wed, 15 Nov 1995 00:00:00 GMT');

where 'obj' is obviously your XMLHTTP object. I have it like this:

obj.onreadystatechange = onResponse;
obj.open("GET", ajaxUrl, true);
obj.setRequestHeader('If-Modified-Since', 'Wed, 15 Nov 1995 00:00:00 GMT');

onResponse is just a my function which handles the responseText and readyState code.

6:13 pm on Dec 23, 2006 (gmt 0)

Senior Member

WebmasterWorld Senior Member 10+ Year Member

joined:Feb 27, 2001
votes: 0

Experimental programming ... love it ;)
8:30 pm on Dec 24, 2006 (gmt 0)

New User

5+ Year Member

joined:July 22, 2006
votes: 0

I thought IE is ultimately. but...
9:44 pm on Dec 24, 2006 (gmt 0)

Senior Member

WebmasterWorld Senior Member 10+ Year Member

joined:Feb 21, 2005
posts: 1526
votes: 0

I dunno if this is considered an "inappropriate link" or not, but I consider it entirely appropriate to the conversation:

User Friendly for December 15th, 2006 [ars.userfriendly.org]