homepage Welcome to WebmasterWorld Guest from 54.198.130.203
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member

Home / Forums Index / Code, Content, and Presentation / JavaScript and AJAX
Forum Library, Charter, Moderator: open

JavaScript and AJAX Forum

    
A Night at the Opera, with a Firefox, while on Safari
A Few Notes on How Browsers Behave Differently in AJAX
cmarshall




msg:3195002
 8:12 pm on Dec 20, 2006 (gmt 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.

Sequence:

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]

 

DrDoc




msg:3196155
 5:19 pm on Dec 21, 2006 (gmt 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.

lobo235




msg:3197404
 5:17 pm on Dec 22, 2006 (gmt 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.

StupidScript




msg:3197457
 6:33 pm on Dec 22, 2006 (gmt 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?

cmarshall




msg:3197506
 7:53 pm on Dec 22, 2006 (gmt 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:

<?php
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.";
?>

cmarshall




msg:3197614
 9:48 pm on Dec 22, 2006 (gmt 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.

carguy84




msg:3197617
 9:49 pm on Dec 22, 2006 (gmt 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:

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

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

physics




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

Experimental programming ... love it ;)

codemeit




msg:3199031
 8:30 pm on Dec 24, 2006 (gmt 0)

I thought IE is ultimately. but...

cmarshall




msg:3199091
 9:44 pm on Dec 24, 2006 (gmt 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]

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / JavaScript and AJAX
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved