window.onbeforeunload, закрытие браузера и синхронный AJAX

Я искал любой разумный пример ситуации, когда синхронный AJAX имеет смысл. Я нашел этот SO question, где автор упоминает window.onbeforeunload и утверждает, что "запрос никогда не остановится", если Вызов AJAX был асинхронным.

Кто-нибудь может это объяснить? Я имею в виду - window.onbeforeunload запускается, когда пользователь хочет закрыть вкладку. Что должно было произойти, чтобы вкладка оставалась живой, даже если кто-то щелкнул, чтобы закрыть ее? Может ли кто-нибудь привести более конкретный пример?


person ducin    schedule 16.01.2015    source источник
comment
Браузер закроет окно, и все запросы, запущенные из него, будут уничтожены. Ник Крейвер говорит об этом в своем посте. Синхронный httpRequest в beforeunload остановит выполнение скрипта, предотвращая выгрузку до тех пор, пока запрос не будет разрешен.   -  person Mouser    schedule 16.01.2015
comment
@Mouser А, кажется, я понял. Поэтому, когда пользователь нажимает кнопку закрытия окна, запускается событие beforeunload. Он содержит некоторый вызов AJAX. В случае асинхронности вызов будет запущен, его успешный обратный вызов откладывается до тех пор, пока не поступит ответ сервера, а скрипт продолжит работу и немедленно умрет. В случае синхронного AJAX весь скрипт замораживается, чтобы убедиться, что ответ приходит, а затем окно благополучно закрывается. Это правильно?   -  person ducin    schedule 16.01.2015
comment
@tkoomzaaskz: Совершенно верно.   -  person Amadan    schedule 16.01.2015


Ответы (2)


Он не сказал, что запрос никогда не остановится; он сказал, что это никогда не будет завершено. То есть у вашего кода нет надежды когда-либо получить ответ, потому что среда выполнения (окно) исчезнет до того, как это произойдет.

Вкладка закроется, когда window.onbeforeunload выйдет с истинным значением. Таким образом, пока он работает, страница ожидает возвращаемого значения, а не закрывается. Это позволяет отправлять синхронный AJAX, а также получать и обрабатывать ответ. Если запрос асинхронный, код создает объект XHR, затем завершается, и страница (и ваш код) исчезает.

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

person Amadan    schedule 16.01.2015
comment
это было сложно, но я, наконец, понял. Но можете ли вы привести какой-либо реальный пример этого? Какой вызов AJAX мне нужно запустить при закрытии вкладки, предполагая, что мне нужно получить ответ от сервера? - person ducin; 16.01.2015
comment
Какой вызов AJAX вам нужно запустить? Я не знаю. Если вы создали форум, вы можете отслеживать онлайн-пользователей и удалять пользователя из списка, когда он закрывает ваше окно. Если бы вы были серийным убийцей, вы могли бы удаленно активировать бомбу, когда пользователь закрывает ваше окно. Зависит от вашего приложения. (Отказ от ответственности: я не одобряю запуск бомб из onbeforeunload. Не делайте этого.) - person Amadan; 16.01.2015

Что должно было произойти, чтобы вкладка оставалась живой, даже если кто-то щелкнул, чтобы закрыть ее? Может ли кто-нибудь привести более конкретный пример?

Отправка синхронного XMLHttpRequest при выгрузке — единственный способ гарантировать доставку данных сеанса, когда пользовательский агент выгружает страницу (и может больше никогда не посещать ваш сайт повторно). Для этого есть два конкретных случая:

  1. Отслеживание — отслеживание и создание отчетов об общем времени сеанса посещения страницы пользователем.
  2. Пакетная обработка. Объединение и отсрочка доставки пакетных данных сеанса для уменьшения количества запросов к серверу.

спецификация Beacon (navigator.sendBeacon) была разработана для оптимизации этого конкретного случая, позволяя отправлять асинхронные запросы. гарантированно будет выполнено даже после выгрузки страницы.

person wjordan    schedule 24.07.2017