两个同步的AJAX请求不会并行运行

我有两个同时运行的AJAX请求的问题。 我有一个正在导出数据到XSLX的PHP脚本。 这个操作需要很多时间,所以我正试图向用户显示进度。 我正在使用AJAX和数据库方法。 其实,我很确定它曾经工作,但我不明白为什么,它不再在任何浏览器工作。 新的浏览器有什么改变吗?

$(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); }); 
  • 进度在数据库中正确更新
  • JS计时器正在尝试获取进度,我可以在控制台中看到它,但是所有这些请求都会加载第一个脚本的整个持续时间,脚本结束后,会加载这些ajax进度调用

那么,为什么第二个AJAX调用等待第一个完成呢?

听起来像会话阻塞问题

默认情况下,PHP将会话数据写入文件。 当使用session_start()启动会话时,会打开文件进行写入并将其locking,以防止同时进行编辑。 这意味着对于使用会话通过PHP脚本的每个请求,都必须等待第一个会话使用该文件完成。

解决这个问题的方法是将PHP会话更改为不使用文件或closures会话,如下所示:

 <?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. 

经过一番拉动之后,我发现了一种方式,这些非平行的AJAX请求可以发生,完全独立于PHP会话处理…因此,我只是在这里发布它,只是为了通过谷歌同样通过相同的人问题。

XDebug可以导致这种情况,如果Zend Debugger也可以,我也不会感到惊讶。

就我而言,我有:

  • 安装在我的本地LAMP堆栈上的XDebug
  • 启用xdebug.remote_autostart
  • 我的IDE接受入站debugging器连接,即使没有断点处于活动状态

这导致我所有的AJAXtesting顺序运行,无论如何。 回想起来,从debugging的angular度来看,强制顺序处理是很有意义的,但是我根本没有注意到我的IDE仍然在幕后进行交互。

在告诉IDE完全停止监听之后,并行运行恢复,我能够重现我一直在寻找的竞争条件。

请注意,如果启用了输出缓冲(默认值为PHP 7+),那么session_write_close()[chrislondon的回答]可能无法解决问题。 您必须在php.ini中设置output_buffering = Off,否则会话将不会正确closures。

你也可以设置

 async: true, 

在使用API​​时,您有时需要向不同的端点发出多个AJAX请求。 在发布下一个请求之前,您可以通过使用jQuery的$ .when()函数并行请求数据来加快jQuery的速度:

并行运行多个AJAX请求

a.php生成一个主要的HTML页面,其中包含两个同时对b.php和c.php的AJAX调用。 为了使b.php和c.php共享会话variables,会话variables必须在第一次AJAX调用之前存在。 如果这是真的,a.php和b.php可以更改会话variables的值并查看彼此的值。 因此,在生成HTML页面时使用a.php创build会话variables。 (至less这是如何与罗杰斯共享networking托pipe。)