Two simultaneous AJAX requests won't run in pa

2019-01-04 12:55发布

I have problem with two simultaneous AJAX requests running. I have a PHP script which is exporting data to XSLX. This operation take a lot of time, so I'm trying to show progress to the user. I'm using AJAX and database approach. Actually, I'm pretty sure it used to work but I can't figure out why, it's no longer working in any browser. Did something change in new browsers?

$(document).ready(function() {

        $("#progressbar").progressbar();

        $.ajax({
            type: "POST",
            url: "{$BASE_URL}/export/project/ajaxExport",
            data: "type={$type}&progressUid={$progressUid}" // unique ID I'm using to track progress from database
        }).done(function(data) {
            $("#progressbar-box").hide();
            clearInterval(progressInterval);
        });

        progressInterval = setInterval(function() {
            $.ajax({
                type: "POST",
                url: "{$BASE_URL}/ajax/progressShow",
                data: "statusId={$progressUid}" // the same uinque ID
            }).done(function(data) {
                data = jQuery.parseJSON(data);
                $("#progressbar").progressbar({ value: parseInt(data.progress) });
                if (data.title) { $("#progressbar-title").text(data.title); }
            });
        }, 500);

    });
  • the progress is correctly updating in database
  • the JS timer is trying to get the progress, I can see it in console, but all these request are loading the whole duration of the first script, as soon as the script ends, these ajax progress calls are loaded

So, why is the second AJAX call waiting for the first one to finish?

6条回答
做个烂人
2楼-- · 2019-01-04 13:40

After a bit of hair-pulling, I found one other way that these non-parallel AJAX requests can happen, totally independent of PHP session-handling... So I'm posting it here just for anyone getting here through Google with the same problem.

XDebug can cause this, and I wouldn't be surprised if Zend Debugger could too.

In my case, I had:

  • XDebug installed on my local LAMP stack
  • xdebug.remote_autostart enabled
  • My IDE accepting inbound debugger-connections, even though no breakpoints were active

This caused all my AJAX tests to run sequentially, no matter what. In retrospect it makes a lot of sense (from the standpoint of debugging things) to force sequential processing, but I simply hadn't noticed that my IDE was still interacting behind-the-scenes.

After telling the IDE to stop listening entirely, parallel runs resumed and I was able to reproduce the race-condition I had been looking for.

查看更多
迷人小祖宗
3楼-- · 2019-01-04 13:51

Sounds like a session blocking issue

By default PHP writes its session data to a file. When you initiate a session with session_start() it opens the file for writing and locks it to prevent concurrent edits. That means that for each request going through a PHP script using a session has to wait for the first session to be done with the file.

The way to fix this is to change PHP sessions to not use files or to close your session write like so:

<?php
    session_start(); // starting the session

    $_SESSION['foo'] = 'bar'; // Write data to the session if you want to

    session_write_close(); // close the session file and release the lock

    echo $_SESSION['foo']; // You can still read from the session.
查看更多
【Aperson】
4楼-- · 2019-01-04 13:51

You could also set

async: true,
查看更多
够拽才男人
5楼-- · 2019-01-04 13:56

Be aware, that session_write_close() [answer of chrislondon] may not resolve the problem, if You have enabled output buffering (default in PHP 7+). You have to set output_buffering = Off in php.ini, otherwise session won't be closed correctly.

查看更多
叼着烟拽天下
6楼-- · 2019-01-04 13:57

When working with APIs, you sometimes need to issue multiple AJAX requests to different endpoints. Instead of waiting for one request to complete before issuing the next, you can speed things up with jQuery by requesting the data in parallel, by using jQuery's $.when() function:

Run multiple AJAX requests in parallel

查看更多
7楼-- · 2019-01-04 13:57

a.php generates a main HTML page that contains two simultaneous AJAX calls to b.php and c.php. In order for b.php and c.php to share session variables, the session variables must exist BEFORE the first AJAX call. Provided this is true, a.php and b.php can change the value of the session variables and see each other's values. Therefore, create the session variables with a.php while generating the HTML page. (At least that's how it works with Rogers shared web hosting.)

查看更多
登录 后发表回答