Jquery / AJAX在php中处理长任务时输出数据

Good afternoon.

I have the following code, that on submit, sends data to a PHP file, which queries multiple network nodes for health status. The problem is that the tasks take about 40 seconds to complete and during that time there is no output. I tried to use ob_flush and flush. No effect, although I have in the php portion of the code. I still see the loading message and get the complete printout once it's ready. However, flush and ob_flush works in general on my server (tested as standalone script), so that's not the issue.

In my understanding that's the jQuery/ajax call that waits for the code to execute completely before spitting out the printout. I looked through the forums and couldn't find any applicable solution, as most of them are related to "GET" request while I'm using "POST".

Can someone please point me in right direction on this? Is there a way to receive printout while the PHP is still processing the request?

JS Code

$(document).ready(function(){
    $('#userForm3g').on('submit', function(e){
        e.preventDefault();
        e.stopImmediatePropagation();

        $('#response').html("<b>Loading data...</b>");

        $.ajax({
                type: 'POST',
                url: 'myphpfile.php',
                data: $(this).serialize()
            })
            .done(function(data){ 
                $('#response').html(data);
            })
            .fail(function() { 
                alert( "Posting failed." );
            });

        return false;
    });
});

Thanks!

The problem with the approach you mentioned is that there are multiple ways that it can fail: you might forget to clear the php output buffer, or the setting might be tightly controlled for some reason, there could be a proxy or load balancer that waits for the request to complete, or it could also be the web browser (chrome used to render partial content, but they stopped doing this).

There are few answers though:

  • You could use partial responses (which is basically streaming on http). There's a specialized library to do this which I've used before, but I forgot its name. I wouldn't recommend this option though, if it fails it will be tough to find why.
  • You could use any method of long polling, including comet or sockets, but you'll need a compatible server (node.js or reactphp)
  • You could use a 3rd party service like Pusher or OneSignal (they also use the previous approach, but it's more integrated and reliable)