Я реализую отслеживание кликов с различных страниц в нашей корпоративной интрасети, чтобы добавить некоторые крайне необходимые функции популярных ссылок из краудсорсинга («самые популярные ссылки в вашем отделе за последние 24 часа» и т. д.)
Я использую jQuery .live() для привязки к событию mousedown для всех элементов ссылки на странице, фильтрую событие, а затем запускаю псевдо-ajax-запрос с различными данными на внутренний сервер перед возвратом true, чтобы действие ссылки срабатывает:
$("#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.
Вопрос. Было бы лучше, если бы я отправлял запрос POST в ASP? Если (b) является виновником, будет ли он вести себя по-разному для POST и GET? Если это так, я мог бы использовать скрытый iframe/форму для POST данных. однако я подозреваю, что это будет медленнее и неуклюже, и все еще может не успеть. Я бы не смог прослушать, чтобы увидеть, завершается ли запрос, потому что он междоменный.
Вопрос. Можно ли просто добавить в скрипт задержку после запуска запроса GET? Как мне сделать это в однопоточном режиме? Мне нужно вернуть true из моей функции, чтобы в конечном итоге сработало событие по умолчанию, поэтому я не могу использовать setTimeout(). Будет ли срабатывать замкнутый цикл, ожидающий «успеха», и устанавливать некоторую переменную работу? Я беспокоюсь, что это слишком заморозит вещи, и ответ будет замедлен. Я предполагаю, что плагин jQuery delay() тоже просто цикл?
Или что-то еще, о чем я не думал, может быть виновником?
Мне не нужна пуленепробиваемая надежность. Если все ссылки одинаково уловимы в 95% случаев, это нормально. Однако прямо сейчас некоторые ссылки улавливаются в 100% случаев, в то время как другие не улавливаются, что не соответствует тому, чего я хочу достичь.
Заранее спасибо.