Может ли использовать beforeloadload/unload для надежной отправки XmlHttpRequests
В последнее время у меня было срочное требование предоставить моему серверу уведомление о том, что определенная страница моего webapp собирается закрыться. "Легкий peasy", я думал, beforeunload
доступен довольно долгое время. HTML5 "вещь" даже обновила спецификацию (вот что я подумал...) об этом, так как у нас была опция return
строковое значение из обработчика события и т.д., Что дает пользователь может перехватить.
См. страницу MDN о onbeforeunload
Однако, как оказалось, нет никакой официальной спецификации, которая описывает поведение для beforeunload
до этой даты. Единственный официальный документ, который я нашел, был на WHATWG, который, конечно, является лишь предложением для W3C.
Смотрите WHATWG
Пока все хорошо. Мы можем создать синхронизированный запрос XHR в обработчике события beforeunload
. "Большинство" браузеров, дайте этому запросу таймфрейм около 1-2 секунд, чтобы завершить, после чего его убивают. Стандартный асинхронный запрос немедленно уничтожается. Сказав это, я даже не могу сказать, "where" я знаю это, похоже, что сплетни и из уст в уста смотрят на него сейчас. Даже это, он работает в Firefox + Chrome, мы не можем полагаться на это, можем ли мы?
Есть ли текущая дискуссия/предложение по WHATWG о beforeunload
?
Любые другие официальные ресурсы о событии, которое я, возможно, не нашел?
И самое главное для меня здесь, насколько надежно мы можем отправлять данные через sync-XHR?
Ответы
Ответ 1
Взгляните на navigator.sendBeacon()
, который позволяет надежно отправлять данные на сервер, даже когда страница выгружается. Он в настоящее время находится в черновик спецификации и поддерживается Firefox 31, Chrome 39 (за флагом от 37), за флагом в Opera 24.
Вы можете "сортировать" polyfill его, используя что-то вроде следующего:
navigator.sendBeacon = navigator.sendBeacon || function (url, data) {
var xhr = new XMLHttpRequest();
// Need to send synchronously to have the best chance of data getting
// through to the server
xhr.open('POST', url, false);
xhr.send(data);
};
Дальнейшее чтение:
Ответ 2
Следует иметь в виду, что beforeunload
запускается как расширение Internet Explorer. Автоматически это делает его вторым классом в Интернете. Спецификации не существует, и реализация браузера меняется. Например, Firefox лишь частично реализует его, не отображая строку, только общее сообщение.
Кроме того, даже если он полностью реализован, он не защищает от всех возможных сценариев разгрузки, например, пользователь завершил работу процессора, обозреватель браузера или компьютер был отключен. Даже игнорируя эти экстремальные сценарии, я подозреваю, что может быть возможно настроить браузер для игнорирования таких запросов.
Я чувствую, что вы не должны полагаться на это сообщение, чтобы спасти вас. Если это веб-приложение является внутренним, я бы предложил обучить их использовать кнопки Save
или Close
или любые другие, а не только закрывать вкладку. Если он внешний, возможно, заглянуть в автоматическое сохранение, поскольку пользователь делает свою работу?
Ответ 3
Sync XHR является ведущим источником зависаний браузера, на который приходится почти 10% зависаний: http://blogs.msdn.com/b/ieinternals/archive/2011/08/03/do-not-use-xmlhttprequest-in-synchronous-mode-unless-you-like-to-hang.aspx
В IE даже синхронизация XHR может быть "прервана", если для запроса требуются сеансы проверки подлинности Windows, или если отправлено тело POST. Вы можете обнаружить, что отправляются только заголовки первого неаутентифицированного запроса.