It is possible, with polling.  The tricky part will be coordinating the process for multiple users on the server side.  I'll explain the workflow below.
The Method
/**
 * Polls a URL until server indicates task is complete,
 * then sends a final request for those results.
 * 
 * Requires jQuery 1.4+.
 */
function poll(params) {
    // offer default params
    params = $.extend({
        error: function(xhr, status, err) {
            console.log('Network error: ' + status + ', ' + err);
        },
        progress: function(prog) {
            console.log(prog);
        },
        timeoutMillis: 600000,    // 10 minutes
        intervalMillis: 3000      // 3 seconds
    }, params);
    // kickoff
    _poll(params);
    function _poll(params) {
        $.ajax({
            url: params.url,
            type: 'GET',
            dataType: 'json',
            timeout: params.timeoutMillis,
            data: 'action=poll',
            success: (function(response, status, xhr) {
                if ('progress' in response) {
                    params.progress('Progress: ' + response.progress);
                }
                if ('status' in response) {
                    if (response.status == 'pending') {
                        // slight delay, then poll again
                        // (non-recursive!)
                        setTimeout((function() {
                            _poll(params);
                        }), params.intervalMillis);
                    }
                    else if (response.status == 'cancelled') {
                        params.progress("Task was cancelled");
                    }
                    else {
                        params.progress("Task complete");
                        // done polling; get the results
                        $.ajax({
                            url: params.url,
                            type: 'GET',
                            timeout: params.timeoutMillis,
                            data: 'action=results',
                            success: params.success,
                            error: params.error
                        });
                    }
                }
            }),
            error: params.error
        });
    }
}
Example usage
poll({
    url: '/cgi-bin/trace.cgi',
    progress: function(prog) {
        $('body #progress').text(prog);
    },
    success: function(response, status, xhr) {
        $('body').html(response);
    }
});
Workflow
This method will send a request to the server with parameter "action" set to "poll".  The CGI script should launch its background task, persist some state in the user session, and respond with JSON-formatted strings:
{"status": "pending", "progress": "0%"}
The browser will repeatedly issue these "action=poll" requests until the response indicates completion.  The CGI script must keep track of the task's progress and respond to the browser accordingly.  This will involve session handling and concurrency:
{"status": "pending", "progress": "25%"}
{"status": "pending", "progress": "50%"}
{"status": "pending", "progress": "75%"}
{"status": "complete"}
The browser will then issue a "action=results" request to receive the background task's final payload.  In this example, it's just HTML:
"<p>The answer is: 42</p>"