jQuery ajax async 'true' застревает в моем веб-приложении до тех пор, пока данные не будут возвращены - PullRequest
0 голосов
/ 16 мая 2018

Я работаю над веб-приложением на основе PHP (которое я не создавал).

Я выполняю этот запрос ajax:

$.ajax({
    type: 'POST',
    url: "/potato/ajax.php?module=test_module",
    dataType: 'json',
    async: true,
    data: {
            start_ts: that.start_date,
            stop_ts: that.end_date, 
            submitted: true
    },
    beforeSend: function() {
        console.log('Start: ' + new Date().toLocaleString());
        // Show Chart Loading 
        that.qwChart.showLoading({ 
            color: '#00b0f0', 
            // text: that.returnNumWithPrecent(that.progress)
            text: that.qwChartProgress
        });

        // If data div isn't displayed
        if (!that.dataDisplayed) {
            // Show divs loading
            that.showMainDiv();
        } else {
            that.$qwTbody.slideUp('fast');
            that.$qwTbody.html('');
        }
    },
    complete: function(){},
    success: function(result){
        console.log('End: ' + new Date().toLocaleString());

        // Clear timer
        clearInterval(timer);

        // Set progressbar to 100%
        that.setProgressBarTo100();

        // Show Download Button
        that.downloadBtn.style.display = 'inline-block';

        // Insert Chart Data
        that.insertChartData(result);

        // Insert Table Data
        that.insertTableData(result);
    }
});

И по какой-то причине оно застревает во всем моем веб-приложении, пока не вернет данные.Я знаю, что по умолчанию ajax-запросы установлены в 'true' , но я все равно добавил его, просто чтобы убедиться, что это так.Если это асинхронный режим, он должен выполнять свою работу без зависания моего веб-приложения, я прав?В чем может быть проблема?Это проблема на стороне сервера?Как мне отладить эту ситуацию?

Редактировать. Под словом «застрял» я имею в виду - когда я жду ответа после отправки вызова ajax, обновления страницы или параллельного открытия других страниц (только в моем веб-приложении), отображается белый экран загрузки.Всякий раз, когда ajax-вызов возвращает данные - белая страница загружается на запрошенную страницу.

Данные возвращаются из файла PHP:

<?php 
require_once("/www/common/api/db.php");

    if (!empty($_POST['submitted'])) {

    // error_reporting(-1);
    // Users Array:
    $users      = get_qw_data($start_ts_to_date, $stop_ts_to_date);

    // Summary Array:
    $summary    = get_qw_summary($users);

    // QW Score Array:
    $qws        = get_qw_score($users);

    // Generate CSV Report files
    /* Remove old:*/ 
    if (!is_file_dir_exist($customer))
        create_qw_directory($customer);

    /* Report #1: */ users_apps_google_macros_ma($users['users'], $customer);
    /* Report #2: */ usage_and_qw_summary($summary, $customer);
    /* Report #3: */ qw_score($qws, $customer);
    /* Zip Files: */ zip_qw_files($customer);

    echo json_encode($qws);
}

1 Ответ

0 голосов
/ 16 мая 2018

Сеансы PHP являются основным кандидатом для «зависания» других запросов, поскольку файл сеанса блокируется от записи, поэтому, пока один запущенный экземпляр скрипта имеет открытый сеанс, все остальные должны ждать.

Решением этого является вызов session_write_close как можно скорее.


Немного расширенное объяснение:

Механизм хранения по умолчанию для данных сеанса - это простофайловая система.Для каждого активного сеанса PHP просто помещает файл в сконфигурированный каталог сеанса и записывает в него содержимое $ _SESSION, чтобы его можно было прочитать оттуда при следующем запросе, который должен получить к нему доступ.

Теперь, если несколько экземпляров PHP-скрипта попытались записать измененные данные сеанса в этот файл «одновременно», это, очевидно, имело бы большой потенциал конфликта / ошибки.

Поэтому PHP устанавливает блокировку записи в файле сеанса, как толькопоскольку один экземпляр сценария обращается к сеансу - всем остальным, другим запросам (к тому же сценарию или другому, также использующему сеанс), придется ждать, пока первый сценарий не будет завершен с сеансом, и блокировка записи будет снята.снова.

По умолчанию это происходит, когда скрипт завершается.Но если у вас более длинные скрипты, это может легко привести к таким «блокирующим» эффектам, которые вы испытываете здесь.Решением этой проблемы является явное указание PHP (через session_write_close): «Я закончил сессию здесь, с этого момента я не собираюсь записывать в нее какие-либо новые / измененные данные - так что не стесняйтесь снимать блокировку, поэтомучто следующий скрипт может начать чтение данных сеанса ».

Важно то, что вы делаете это только после того, как ваш скрипт завершил манипулирование любыми данными сеанса.Вы можете все еще читать из $ _SESSION в течение остальной части сценария - но вы больше не можете писать в него.(Таким образом, что-то вроде $_SESSION['foo'] = 'bar'; может завершиться сбоем после того, как вы выпустили сеанс.)

Если единственная цель, которую сеанс выполняет в данный момент (в этом конкретном сценарии), это проверка аутентификации пользователя, то вы можетезакройте сеанс сразу после этого.Затем оставшаяся часть сценария может запускаться сколько угодно, не блокируя другим сценариям доступ к тому же сеансу.


Это не ограничивается запросами AJAX - это только один изместа, где вы обычно замечаете подобные вещи, потому что в противном случае у вас обычно не так много запросов, использующих сеанс, запущенный «параллельно».Но если бы вам приходилось открывать долго выполняющийся скрипт несколько раз на нескольких вкладках браузера, вы бы заметили тот же эффект - на первой вкладке скрипт будет работать и работать, тогда как на следующих вкладках вы должны заметить, что этизапросы также «зависают», если предыдущий экземпляр скрипта удерживает блокировку записи в сеансе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...