What I've basically done is create a progress bar that tracks server progress. When the submit button is clicked the server starts it's task (a loop) while updating an XML file at the end of each loop to track that progress. The XML looks like this...

Code:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<root>
  <numcurrent>0</numcurrent>
  <numtotal>40</numtotal>
</root>
Simultaneously, an AJAX loop is started (via the liveUpdate() function) that grabs the XML file once per second and updates the page. This works peachy keen in every browser save Safari and Chrome (WebKit-based browsers).

Here's the script all commented up the wazoo...

Code:
//GLOBAL VARIABLES
var xhr = false;        //Stores our XMLHttpRequest object
var strFile = false;    //Stores our XML filename

//<summary> Builds the request for the XML and sends it to the server. </summary>
//<param name="strURL"> The URL of the XML file to requested. </param>
function xhrRequest(strURL)
{    
    xhr = false;    //Reset xhr to false if it's not

    //START: We instantiate the XMLHttpRequest object as xhr
    if (window.XMLHttpRequest)      //First we see if the browser supports XMLHttpRequest
    {
        xhr = new XMLHttpRequest(); //If it does, we create a new XMLHttpRequest object
    }
    else if (window.ActiveXObject)  //If that fails (IE6) we see if the browser supports ActiveX
    {
        try
        {
            xhr = new ActiveXObject("Microsoft.XMLHTTP"); //If the browser does, we use ActiveX instead
        }
        catch (e) 
        {
            //We failed at creating ANY XMLHttpRequest object. Error will be displayed in next IF block.
        }
    }
    //END: We have instantiated the XMLHttpRequest (hopefully) as xhr
    
    //START: We build the request for the XML file and send it to the server
    if (xhr) //Remember, if the above instantiation failed, xhr will be false
    {
        xhr.onreadystatechange = function(){xhrCatch();}  //Every time the state changes (ie, from 2-3 or 3-4), we run the showData function.
        xhr.open("GET",strURL,true);                      //Build the request for xmldoc.xml
        xhr.send(null);                                   //Send the request (we use null because we're not sending additional content)
    }
    else    //if we have a problem we want to output an error.
    {
        alert("ERROR: There was a problem creating the XMLHttpRequest!");
    }
    //END: We have sent the request to the server and triggered xhrCatch() (hopefully)
}

//<summary> Gets the response from the server (fetches the XML). </summary>
function xhrCatch() //This is run whenever the state changes and is used to update the page.
{
    if (xhr.readyState == 4 || xhr.readyState == 0) //We only want to do something if the document we specified is fully loaded
    {
        if (xhr.status == 200) //If the server doesn't return an error code (anything other than 200)
        {
            doStuff(); //Everything succeeded, lets work with our XML
        }
        else if (xhr.status != 404)   //if we have a problem we want to output an error.
        {
            //alert("ERROR: The server reported an error of " + xhr.status + ": " + xhr.statusText); //Alert us if there's a problem (ie: "The server reported an error of 401: Unauthorized")
        }
    }
}

//<summary> Runs the check. </summary>
function liveUpdate(strXML)
{
    //Put our XML filename into the global variable strFile
    strFile = strXML.toString();
    
    //Make the XMLHttpRequest
    xhrRequest(strFile);
}

//<summary> Does things with the XML we retreived. </summary>
function doStuff()
{
    var progressArray = new Array(); //We create a new array to store our XML data later
    
    if (xhr.responseXML) //So long as our responseXML isn't empty/null
    {
        var iCurrent = xhr.responseXML.getElementsByTagName("numcurrent")[0].firstChild.data; //Get the current state from the XML
        var iMax = xhr.responseXML.getElementsByTagName("numtotal")[0].firstChild.data;       //Get the final state from the XML
        var iPercentage = Math.round((iCurrent/iMax)*100);                                    //Create a percentage (int)
                
        //getElementsByTagName always returns an array, so we have to select element [0] (the first element) then the firstChild
        //of that element (itself), then we return the data from that.
        document.getElementById("progressData").innerHTML = "Processing " + iCurrent + " of " + iMax;//Display the current progress
        document.getElementById("progressNum").innerHTML = iPercentage+"%";         //Display the percentage number
        document.getElementById("progressBar").style.width = iPercentage+"%";       //Update the graphic progress bar
        
        //document.getElementById("giveMeData").innerHTML += iCurrent + " / " + iMax + "<br />"; 
    }
    else
    {
        alert("xhr.resonseXML is null! " + xhr.responseXML.parseError.errorCode); //This should never happen if we've made it to this point, but just in case.
    }
    
    setTimeout("liveUpdate('"+strFile+"');",1000); //Run liveUpdate() again after a delay (we're looping on purpose)
}
After doing some troubleshooting here's what I found...

If postback is disabled for the submit button (onclick="return false;") then Safari has no trouble fetching the XML. I can even update the XML by hand and see the results immediately while AJAX is looping.

If postback is NOT disabled, then the XMLHttpRequest fails. xhr.status, xhr.readyState, xhr.responseText/xhr.responseXML, etc will all stay null. As if either the request was not sent or not received.

I further tested this by launching liveUpdate() onload with no Javascript attached to the submit button. As before I could update the XML by hand and see the results immediately. As soon as the submit button was clicked (which launches the server-side loop that also updates the XML), Ajax immediately stopped updating the page.

I'm starting to think this a bug in WebKit, but maybe I'm missing something here. Does anyone know why the XMLHttpRequest in Safari stops working when a submit button with a server behavior is clicked?