Исключение нулевого указателя генерируется, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:
null
. null
. null
, как если бы это был массив. null
, как если бы это был массив. null
как будто это было значение Throwable. Приложения должны бросать экземпляры этого класса, чтобы указать на другие незаконные использования объекта null
.
Ссылка: http://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html
Есть события unload
и beforeunload
javascript, но они ненадежны для запроса Ajax (не гарантируется, что запрос, инициированный в одном из этих событий, достигнет сервера).
Поэтому делать это настоятельно не рекомендуется, и вы должны искать альтернативу.
Если вам это определенно нужно, рассмотрите «пинговое» решение. Отправляйте запрос каждую минуту, в основном говоря серверу «Я все еще здесь». Затем, если сервер не получает такой запрос более двух минут (вы должны учитывать задержки и т. Д.), Вы считаете, что клиент офлайн.
Другое решение было бы используйте unload
или beforeunload
для выполнения запроса Sjax (синхронный JavaScript и XML), но это совершенно не рекомендуется. Выполнение этого будет в основном заморозить браузер пользователя до тех пор, пока запрос не будет завершен, что им не понравится (даже если запрос занимает мало времени).
Основываясь на этом другом ответе .
Чтобы все было ясно, в 2018 году Beacon API является решением этой проблемы (в почти каждый браузер ])
Запросы Beacon гарантируются, прежде чем страница будет выгружена, и они будут запущены до завершения, без запроса блокировки.
blockquote>Вы можете используйте его внутри
onunload
события и будьте уверены, что он будет отправлен.$(window).on('unload', function() { var URL = "https://example.com/foo"; var data = "bar"; navigator.sendBeacon(URL, data); });
Отличная запись в блоге: http://usefulangle.com/post/62/javascript-send-data -to-server-on-page-exit-reload-redirect
API Beacon: https://developer.mozilla.org/en-US/docs/Web/API / Beacon_API / Using_the_Beacon_API
Выбранный ответ правильный, что вы не можете гарантировать, что браузер отправит запрос xhr, но в зависимости от браузера вы можете надежно отправить запрос на вкладке или закрытии окна.
Обычно, браузер закрывается до выполнения xhr.send (). Chrome и edge выглядят так, что они ждут, когда цикл событий javascript будет опущен до закрытия окна. Они также запускают запрос xhr в другом потоке, чем цикл событий javascript. Это означает, что если вы можете держать цикл событий достаточно длинным, xhr успешно сработает. Например, я протестировал отправку запроса xhr, а затем счет до 100 000 000. Это работало очень последовательно как для хрома, так и для меня. Если вы используете angularjs, перенос вашего вызова на $ http in $ apply делает то же самое.
IE, похоже, немного отличается. Я не думаю, что IE ждет, пока цикл цикла не будет опущен, или даже для текущего стека стека. Хотя иногда он будет правильно отправлять запрос, то, что кажется гораздо чаще (80% -90% времени), заключается в том, что IE закроет окно или вкладку до того, как запрос xhr будет полностью выполнен, что приведет лишь к частичному сообщению послан. В основном сервер получает почтовый запрос, но нет тела.
Для потомков вот код, который я использовал в качестве функции window.onbeforeunload для прослушивания:
var xhr = new XMLHttpRequest();
xhr.open("POST", <your url here>);
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
var payload = {id: "123456789"};
xhr.send(JSON.stringify(payload));
for(var i = 0; i < 100000000; i++) {}
Я тестировал в :
Chrome 61.0.3163.100
IE 11.608.15063.0CO
Edge 40.15063.0.0
Я также хотел достичь той же функциональности & amp; напомнил этот ответ от Felix (, не гарантируется, что запрос, инициированный в одном из этих событий, достигнет сервера ).
Чтобы запрос дошел до сервера, мы попробовали ниже кода: -
onbeforeunload = function() {
//Your code goes here.
return "";
}
Мы используем браузер IE и amp; теперь, когда пользователь закрывает браузер, он получает диалог подтверждения из-за return "";
& amp; ожидает подтверждения пользователя & amp; это время ожидания делает запрос доступ к серверу.
Использование:
<body onUnload="javascript:">
Он должен захватывать все, кроме выключения программы браузера.
Я согласен с идеей Феликса, и я решил проблему с этим решением, и теперь я хочу очистить решение на стороне сервера:
1. передать запрос с клиентской стороны на сервер
2.save время последнего запроса, полученного в переменной
. 3. Проверьте время сервера и сравните его с переменной последнего полученного запроса
4.если результат больше, чем вы ожидаете, начните запуск кода, который вы хотите запустить, когда окна закрыты ...
1) Если вы ищете способ работы во всех браузерах, то самым безопасным способом является отправка синхронного AJAX на сервер. Это не хороший метод, но, по крайней мере, убедитесь, что вы не отправляете слишком много данных на сервер, а сервер работает быстро.
2) Вы также можете использовать асинхронный запрос AJAX, и используйте функцию ignore_user_abort на сервере (если вы используете PHP). Однако ignore_user_abort сильно зависит от конфигурации сервера. Убедитесь, что вы хорошо его протестировали.
3) Для современных браузеров вы не должны отправлять запрос AJAX. Вы должны использовать новый метод navigator.sendBeacon для отправки данных на сервер асинхронно и без блокировки загрузки следующей страницы. Поскольку вы хотите отправить данные на сервер до того, как пользователь переместится с страницы, вы можете использовать этот метод в обработчике события unload .
$(window).on('unload', function() {
var fd = new FormData();
fd.append('ajax_data', 22);
navigator.sendBeacon('ajax.php', fd);
});
Также кажется, что быть полигоном для sendBeacon . Применяется синхронный AJAX, если метод не доступен изначально.
ВАЖНО ДЛЯ МОБИЛЬНЫХ УСТРОЙСТВ: Обратите внимание, что обработчик событий unload не гарантируется для мобильных телефонов. Но ожидается, что событие visibilitychange будет запущено. Поэтому для мобильных устройств вашему коду сбора данных может потребоваться небольшая настройка.
Вы можете ссылаться на мою статью в блоге для реализации кода всеми тремя способами.
return "a string";
в вашем обработчикеbeforeunload
(выполнениеconfirm()
не будет работать). – Felix 29 May 2011 в 20:58