У меня проблема с двумя одновременными запросами AJAX. У меня есть PHP-скрипт, который экспортирует данные в XSLX. Эта операция занимает много времени, поэтому я пытаюсь показать прогресс пользователю. Я использую подход 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); });
Итак, почему второй вызов AJAX ждет завершения первого?
Звучит как проблема блокировки сеанса
По умолчанию PHP записывает свои данные сеанса в файл. Когда вы начинаете сеанс с session_start (), он открывает файл для записи и блокирует его для предотвращения одновременных изменений. Это означает, что для каждого запроса, проходящего через PHP-скрипт с использованием сеанса, необходимо дождаться завершения первого сеанса с файлом.
Способ исправить это – изменить сеансы PHP, чтобы не использовать файлы или закрыть сеанс записи так:
<?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 … Поэтому я размещаю его здесь только для тех, кто попадает сюда через Google с тем же проблема.
XDebug может вызвать это, и я не удивлюсь, если Zend Debugger тоже может.
В моем случае у меня было:
xdebug.remote_autostart
Это заставило все мои тесты AJAX работать последовательно, несмотря ни на что. Оглядываясь назад, это имеет большой смысл (с точки зрения отладки вещей) для принудительной последовательной обработки, но я просто не заметил, что моя среда IDE все еще взаимодействует за кадром.
После того, как среда IDE перестала слушать, возобновились параллельные прогоны, и я смог воспроизвести состояние гонки, которое я искал.
Имейте в виду, что session_write_close () [ответ chrislondon] может не решить проблему, если вы включили буферизацию вывода (по умолчанию в PHP 7+). Вы должны установить output_buffering = Off в php.ini, иначе сеанс не будет закрыт правильно.
Вы также можете установить
async: true,
При работе с API-интерфейсами вам иногда необходимо выдать несколько запросов AJAX для разных конечных точек. Вместо того, чтобы ждать завершения одного запроса перед выпуском следующего, вы можете ускорить работу с jQuery, запросив данные параллельно, используя функцию $ .when () jQuery:
Запуск нескольких запросов AJAX параллельно
a.php создает основную HTML-страницу, содержащую два одновременных вызова AJAX для b.php и c.php. Для того чтобы b.php и c.php делились переменными сеанса, переменные сеанса должны существовать ПЕРЕД первым вызовом AJAX. Если это так, a.php и b.php могут изменять значение переменных сеанса и видеть значения друг друга. Поэтому создайте переменные сеанса с помощью a.php при создании HTML-страницы. (По крайней мере, так оно работает с общим хостингом Роджерса.)