JavaScript / jQuery: как убедиться, что междоменное событие отслеживания кликов прошло успешно, прежде чем пользователь покинет страницу? - PullRequest
1 голос
/ 17 июля 2010

Я внедряю отслеживание кликов на различных страницах в нашей корпоративной интранете, чтобы добавить некоторые крайне необходимые функции популярных ссылок («самые популярные ссылки в вашем отделе за последние 24 часа» и т. Д.)

Я использую jQuery .live () для привязки к событию mousedown для всех элементов ссылки на странице, фильтрации события, а затем запускаю псевдо-ajax-запрос с различными данными на внутреннем сервере перед возвратом.истина, так что действие ссылки срабатывает:

$("#contentarea a").live("mousedown", function(ev) {
    //
    // detect event, find closest link, process it  here
    //
    $.ajax({
        url: 'my-url',
        cache: false,
        dataType: 'jsonp',
        jsonp: 'cb',
        data: myDataString,
        success: function() {
            // silence is golden -- server does send success JSONP but 
            // regardless of success or failure, we allow the user to continue
        }
    });

    return true; // allow event to continue, user leaves the page.
}

Как вы, вероятно, можете догадаться из вышеизложенного, у меня есть несколько ограничений:

  • Внутренний сервер отслеживания находится на другомсубдомен со страницы вызова.Я не могу обойти это.Вот почему я использую JSONP (и GET) в отличие от правильного AJAX с POST.Я не могу реализовать прокси-сервер AJAX, поскольку веб-серверы не имеют исходящего сетевого доступа для сценариев.
  • Это, вероятно, не имеет значения, но в интересах полного раскрытия содержание и сценарий находятся внутри "основногоiframe (и это не изменится. Я, вероятно, в конечном итоге переместу прослушиватель событий в родительский фрейм, чтобы отслеживать его ссылки и весь дочерний контент, но шаг 1 заставляет его работать должным образом в упрощенном случае «1 потомок»окно").Родитель и потомок - это один и тот же домен.
  • Бэк-энд - это IIS / ASP (опять же, ограничение - не спрашивайте!), Поэтому я не могу немедленно разветвить процесс бэк-энда или прекратить каким-либо другим образомответ, но продолжайте обработку, как я мог бы на лучшей платформе

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

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

Я исключил ошибки скрипта - кажется, что либо:

(a) запрос никогда не делает егона задний план во времени;или

(b) запрос делает его, но ASP обнаруживает, что вскоре после этого клиент отключается, и, поскольку это запрос GET, не обрабатывает его.

Я подозреваю (б), поскольку задержка на сервере очень быстрая и многие ссылки регистрируются нормально.Если я включаю всплывающее окно с предупреждением после возникновения события или устанавливаю возвращаемое значение в false, щелчок регистрируется в порядке.

Любые рекомендации о том, как я могу решить эту проблему (в контексте, который я не могу изменитьмои ограничения)?Я не могу сделать GET-запрос синхронным, так как это не так. AJAX.

Q : Будет ли это работать лучше, если я делаю POST-запрос к ASP?Если (б) виновник, будет ли он вести себя по-разному для POST против GET?Если это так, я мог бы использовать скрытый iframe / форму для размещения данных.однако, я подозреваю, что это будет медленнее и неуклюже, и, возможно, все равно не успеет.Я не смог бы прослушать, если запрос завершен, потому что он междоменный.

Q : Могу ли я просто добавить задержку в сценарий после запуска запроса GETвыкл?Как мне сделать это однопоточным способом?Мне нужно вернуть true из моей функции, чтобы гарантировать, что событие по умолчанию в конечном итоге сработает, поэтому я не могу использовать setTimeout ().Будет ли жесткий цикл ожидания «успеха», чтобы запустить и установить некоторые переменные работы?Я беспокоюсь, что это слишком сильно замерзнет, ​​и реакция замедлится.Я предполагаю, что плагин jQuery delay () - это тоже просто цикл?

Или что-то еще, о чем я не думал, может быть виновником?

Мне не нужно пуленепробиваемоенадежность.Если все ссылки одинаково доступны в 95% случаев, это нормально.Однако прямо сейчас некоторые ссылки можно отлавливать в 100% случаев, в то время как другие не поддаются отлову - что не приведет к тому, чего я хочу достичь.

Заранее спасибо.

Ответы [ 3 ]

0 голосов
/ 17 июля 2010

Я бы попробовал другой подход. Вы можете привязать к другому событию, как:

$(window).unload(function(event) {
  // tracking code here
});
0 голосов
/ 19 июля 2010

Решено!

Короткий ответ: нет надежного способа сделать этот междоменный запрос GET.Я перепробовал все виды, в том числе сохранение события и повторное воспроизведение события позже, и всевозможные хаки, чтобы попытаться заставить это работать.

Затем я попробовал узкие циклы, и они также не были надежными.

Наконец, я просто сдался и использовал динамически созданную форму, которая разместила результаты с целевым значением скрытого iFrame.

То, что работает надежно - этокажется, что браузер делает паузу, чтобы завершить свой запрос POST, прежде чем двигаться дальше, и ASP соблюдает POST.Оказывается, это не "неуклюжий" вообще.Конечно, из-за модели безопасности браузера я не вижу результат ... но это не имеет значения в этом случае.

Я теперь понимаю, что сначала я не пробовал этот вариант.

0 голосов
/ 17 июля 2010

Я бы попытался вернуть false из обработчика событий ссылки, запомнить URL-адрес и перейти на другую страницу только после успешного выполнения запроса JSONP.Надеюсь, это не должно добавить слишком много времени ожидания.Учитывая, что вы находитесь во внутренней сети, все может быть в порядке.

...