Подтвердить что ты не робот

$(window).unload ждать завершения вызова AJAX до выхода из веб-страницы.

В принципе, как только пользователь покидает веб-страницу в моем приложении, мне нужно вызвать PHP script с AJAX, который вставляет время, потраченное на веб-страницу, в базу данных, а затем покидает страницу.

Важно дождаться завершения запроса AJAX, поскольку веб-страницы в моем приложении недоступны для пользователей, если они не потратили определенное время на предыдущей странице (скажем, две минуты).

Вот мой код jquery:

$(document).ready(function() {

    var teid = TEID;
    var startTime = new Date().getTime();

    $(window).unload(function() {
        var timeSpentMilliseconds = new Date().getTime() - startTime;
        var t = timeSpentMilliseconds / 1000 / 60;

        $.ajax({
            type: 'POST',
            url: '/clientarea/utils/record-time',
            data: 'teid=' + teid + '&t=' + t
        });
    });

});

Как мне изменить его, чтобы он дождался завершения запроса AJAX до выхода из веб-страницы?

EDIT:

Или может быть лучше (проще) просто повторить запрос AJAX каждую минуту или около того. Возможно ли это?

4b9b3361

Ответ 1

Ну, вы можете установить async: false на ваш вызов AJAX, чтобы браузер дождался завершения запроса, прежде чем делать что-либо еще, но обратите внимание, что это будет "зависать" браузера в течение всего времени запроса.

$.ajax({
    type: 'POST',
    async: false,
    url: '/clientarea/utils/record-time',
    data: 'teid=' + teid + '&t=' + t
});

Из руководства:

По умолчанию все запросы отправляются асинхронно (т.е. по умолчанию это значение равно true). Если вам нужны синхронные запросы, установите для этого параметра значение false. Междоменные запросы и dataType: запросы "jsonp" не поддерживают синхронную работу. Обратите внимание, что синхронные запросы могут временно блокировать браузер, отключая любые действия, пока запрос активен.

Ответ 2

Как установить cookie в обработчик выгрузки? Сервер должен увидеть его на последующих запросах.

<script>
    $(window).unload(function(){document.cookie='left_on='+(new Date())})
</script>

Ответ 3

Лучшее решение - использовать navigator.sendBeacon. Это совершенно новая функциональность, которая начинает внедряться в новые версии браузеров. Функция доступна в браузерах, новее, чем Chrome 39 и Firefox 31. Она не поддерживается Internet Explorer и Safari на момент написания. Чтобы убедиться, что ваш запрос отправляется в браузерах, которые еще не поддерживают новую функциональность, вы можете использовать это решение:

var navigator.sendBeacon = navigator.sendBeacon || function (url, data) {
  var client = new XMLHttpRequest();
  client.open("POST", url, false); // third parameter indicates sync xhr
  client.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
  client.send(data);
};

Надеюсь, это поможет!

Ответ 4

для меня, у вас не очень хорошая идея, чтобы браузер подождал до закрытия... Просто потому, что, если я действительно хочу его закрыть?...

Если страница беспокоит пользователя, это не хорошо...

Мое предложение на странице, вы ждете 2 минуты (если требуется 2 минуты), а затем отправьте ajax, что пользователь сделал свои 2 минуты...

вы можете проверить его на стороне сервера, если у вас есть 2 минуты или нет...

Ответ 5

Плохая идея попробовать и захватить браузер своих пользователей, так как это даст им плохое чувство и отпустит их.

Если по какой-то причине вы не хотите создавать новую страницу до тех пор, пока пользователь не проведет минимальное время на предыдущем, самое лучшее, что нужно сделать, это пилотная сторона сервера, то есть перенаправление на текущую страницу до тех пор, пока запрашиваемое время не будет прошло.

Вам даже не нужно делать ajax-вызовы, просто сохраните в сеансе временную метку, когда страница была подана, и не показывайте следующую страницу, пока не пройдет определенное количество времени.

Обязательно сообщите пользователям, что они должны ждать, пока новая страница будет готова, возможно, с простым обратным отсчетом JavaScript.

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

Ответ 6

Я думаю, было бы гораздо лучше использовать технику опроса, как вы предлагаете, хотя это вызовет некоторую нагрузку на веб-сервер.

$(document).ready(function() {

    var teid = TEID;
    var startTime = new Date().getTime();

    var ajaxFunc = function() {
        var timeSpentMilliseconds = new Date().getTime() - startTime;
        var t = timeSpentMilliseconds / 1000 / 60;

        $.ajax({
            type: 'POST',
            url: '/clientarea/utils/record-time',
            data: 'teid=' + teid + '&t=' + t
        });
    };

    setInterval(ajaxFunc, 60000);

})

Вы будете рады, если сможете использовать websockets:)

Ответ 7

У метода jQuery.ajax() есть опция async. Если вы установите его на false, вызов будет блокироваться до тех пор, пока ответ не вернется (или он не будет установлен). Я довольно уверен, что это вызовет это, потому что браузер будет работать с обработчиком разгрузки.

Боковое примечание: вы не можете полагаться на это, чтобы работать. Если браузер дает пользователю возможность отменить обработчики выгрузки (что некоторые браузеры делают после некоторого времени ожидания), "время тратится на сайт" никогда не будет обновляться. Вы можете добавить на сайт таймер, который периодически вызывает script на сервере и который обновляет время. У вас не будет точной стоимости, но в вашем случае это не требуется.

Если вам нужно только знать, был ли пользователь на X секунд на странице, вы можете просто установить тайм-аут в обработчике onload (используя setTimeout(function, ms)), который делает вызов, если пользователь потратил необходимое время. Таким образом, нет необходимости в обработчике выгрузки.

Ответ 8

используйте onbeforeunload:

$(document).ready(function(){
  window.onbeforeunload = function(){
     // $.ajax stuff here
     return false;
  }
});

Это, по крайней мере, приведет пользователя messagebox, который спрашивает его, хочет ли он закрыть текущее окно/вкладку.