Запустите скрипт bash через CGI при закрытии окна браузера [duplicate]

Исключение нулевого указателя - это индикатор того, что вы используете объект, не инициализируя его.

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

public class Student {

    private int id;

    public int getId() {
        return this.id;
    }

    public setId(int newId) {
        this.id = newId;
    }
}

Приведенный ниже код дает вам исключение с нулевым указателем.

public class School {

    Student obj_Student;

    public School() {
        try {
            obj_Student.getId();
        }
        catch(Exception e) {
            System.out.println("Null Pointer ");
        }
    }
}

Поскольку вы используете Obj_Student, но вы забыли инициализировать его, как в правильном коде, показанном ниже:

public class School {

    Student obj_Student;

    public School() {
        try {
            obj_Student = new Student();
            obj_Student.setId(12);
            obj_Student.getId();
        }
        catch(Exception e) {
            System.out.println("Null Pointer ");
        }
    }
}
16
задан Jonathan Leffler 24 February 2014 в 02:49
поделиться

7 ответов

Есть события unload и beforeunload javascript, но они ненадежны для запроса Ajax (не гарантируется, что запрос, инициированный в одном из этих событий, достигнет сервера).

Поэтому делать это настоятельно не рекомендуется, и вы должны искать альтернативу.

Если вам это определенно нужно, рассмотрите «пинговое» решение. Отправляйте запрос каждую минуту, в основном говоря серверу «Я все еще здесь». Затем, если сервер не получает такой запрос более двух минут (вы должны учитывать задержки и т. Д.), Вы считаете, что клиент офлайн.


Другое решение было бы используйте unload или beforeunload для выполнения запроса Sjax (синхронный JavaScript и XML), но это совершенно не рекомендуется. Выполнение этого будет в основном заморозить браузер пользователя до тех пор, пока запрос не будет завершен, что им не понравится (даже если запрос занимает мало времени).

29
ответ дан Felix 20 August 2018 в 11:36
поделиться
  • 1
    Хорошо, если он делает выход из системы, то я видел рабочие примеры, когда выгрузка открывает всплывающие окна, которые затем регистрируют пользователя (это решает проблему без guarentee?). – Jonathon 28 May 2011 в 15:34
  • 2
    Нет. Держу пари, там есть блокировщики всплывающих окон, которые не позволяют всплывать в этих событиях. Кроме того, это ужасный UX, чтобы открыть всплывающее окно, когда пользователь закрывает вкладку / окно. – Felix 28 May 2011 в 15:36
  • 3
    Я предполагаю, что проблема заключается в том, что запрос требует времени, и браузер может быть завершен с выгрузкой к моменту его завершения (так что он может никогда не закончиться)? – Jonathon 28 May 2011 в 15:36
  • 4
    Я на самом деле делаю, что я все еще здесь. Но это медленный и уменьшенный пользовательский интерфейс. Кроме того, сокращение интервала «я все еще здесь». может убить сервер с высокой скоростью пользователей. Поэтому я пытался заменить его чем-то другим. Когда вы говорите, что запрос не является надежным, как ненадежный u означает? Я могу использовать это и удваивать его с отправкой сообщений с более высоким интервалом, имеет более 50% успеха. Я думаю, что это может улучшить производительность с обеих сторон (сервер и клиент). – zozo 28 May 2011 в 15:38
  • 5
    Я думаю, что это будет ваш лучший выбор (хотя вам все равно придется пинговать, если вы хотите быть на 100% уверенным). Кстати, способ сделать это - return "a string"; в вашем обработчике beforeunload (выполнение confirm() не будет работать). – Felix 29 May 2011 в 20:58

Основываясь на этом другом ответе .

Чтобы все было ясно, в 2018 году Beacon API является решением этой проблемы (в почти каждый браузер ])

Запросы Beacon гарантируются, прежде чем страница будет выгружена, и они будут запущены до завершения, без запроса блокировки.

Вы можете используйте его внутри 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

1
ответ дан Baishu 20 August 2018 в 11:36
поделиться

Выбранный ответ правильный, что вы не можете гарантировать, что браузер отправит запрос 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

0
ответ дан codepuzzler 20 August 2018 в 11:36
поделиться
  • 1
    Время, затрачиваемое на цикл for, зависит от процессора, JS Engine и других факторов. Немного менее плохая идея заключалась бы в блокировании цикла событий на 100 мс или любом другом значении, которое считается достаточно продолжительным после экспериментов – Greg 1 November 2017 в 02:25

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

Чтобы запрос дошел до сервера, мы попробовали ниже кода: -

onbeforeunload = function() {

    //Your code goes here.

    return "";
} 

Мы используем браузер IE и amp; теперь, когда пользователь закрывает браузер, он получает диалог подтверждения из-за return ""; & amp; ожидает подтверждения пользователя & amp; это время ожидания делает запрос доступ к серверу.

3
ответ дан Jasny - Arnold Daniels 20 August 2018 в 11:36
поделиться
  • 1
    кажется, что текущий Chrome вообще игнорирует это, если в функции beforeunload имеется больше, чем только оператор retrun string. Итак, вы можете сделать return & quot; Вы хотите закрыть? & Quot ;, но вы не можете ничего сделать ... – Michal Politzer 30 March 2017 в 08:01

Использование:

<body onUnload="javascript:">

Он должен захватывать все, кроме выключения программы браузера.

-2
ответ дан Jonathon 20 August 2018 в 11:36
поделиться
  • 1
    hmm (-1), мне было бы очень интересно узнать, что не так с этим методом. Никогда не использовал его сам, но сталкивался с ним много раз, как решение вашей конкретной проблемы. – Jonathon 28 May 2011 в 15:30
  • 2
    Я отправил ответ, в котором я объясняю -1. – Felix 28 May 2011 в 15:32

Я согласен с идеей Феликса, и я решил проблему с этим решением, и теперь я хочу очистить решение на стороне сервера:

1. передать запрос с клиентской стороны на сервер

2.save время последнего запроса, полученного в переменной

. 3. Проверьте время сервера и сравните его с переменной последнего полученного запроса

4.если результат больше, чем вы ожидаете, начните запуск кода, который вы хотите запустить, когда окна закрыты ...

0
ответ дан Ramin Farajpour 20 August 2018 в 11:36
поделиться

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 будет запущено. Поэтому для мобильных устройств вашему коду сбора данных может потребоваться небольшая настройка.

Вы можете ссылаться на мою статью в блоге для реализации кода всеми тремя способами.

5
ответ дан Useful Angle 20 August 2018 в 11:36
поделиться
  • 1
    В 2018 году это лучший ответ. Используйте API-интерфейс маяка. Прочтите статью в блоге, указанную в ответе ( usefulangle.com/post/62/… ) для более подробной информации. – Baishu 24 February 2018 в 09:20
Другие вопросы по тегам:

Похожие вопросы: