Запретить любую форму обновления страницы с помощью jQuery / Javascript

93

Когда пользователь находится на моей странице, я не хочу, чтобы он обновлял страницу.

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

    Вы не можете обновить страницу.

  2. Также, если пользователь открывает новую вкладку и пытается получить доступ к тому же URL-адресу на предыдущей вкладке, он должен получить предупреждение.

    Вы не можете открыть одну и ту же страницу на 2 вкладках

В любом случае я могу сделать это с помощью JavaScript или jQuery? Пункт первый действительно важен.

панкадж
источник
Вы можете обнаружить с помощью API Broadcast Channel ( developer.mozilla.org/en-US/docs/Web/API/Broadcast_Channel_API ) и отправить сообщения для связи между вкладками. Таким образом, используя это, вы можете обнаружить несколько вкладок с одинаковым URL-адресом и заблокировать другие вкладки.
aeXuser264

Ответы:

195

# 1 можно реализовать через window.onbeforeunload.

Например:

<script type="text/javascript">
    window.onbeforeunload = function() {
        return "Dude, are you sure you want to leave? Think of the kittens!";
    }
</script>

Пользователь получит подсказку с сообщением, и ему будет предоставлена ​​возможность остаться на странице или продолжить свой путь. Это становится все более распространенным явлением. Stack Overflow сделает это, если вы попытаетесь уйти со страницы во время набора сообщения. Вы не можете полностью остановить перезагрузку пользователя, но вы можете сделать так, чтобы это звучало очень страшно, если он это сделает.

№2 более или менее невозможно. Даже если вы отслеживали сеансы и входы пользователей, вы все равно не сможете гарантировать, что правильно обнаруживаете вторую вкладку. Например, я могу открыть одно окно и закрыть его. Теперь открываю новое окно. Вы, скорее всего, заметите это как вторую вкладку, хотя я уже закрыл первую. Теперь ваш пользователь не может получить доступ к первому окну, потому что он его закрыл, и он не может получить доступ ко второму окну, потому что вы им запрещаете.

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

Сет
источник
1
Обратите внимание, что событие onbeforeunload недоступно в версиях браузера Opera.
WillyCornbread
1
Есть ли способ что-то сделать, если пользователь решит остаться на странице?
riship89
5
Сделал трюк для меня, хотя вы должны использовать window.addEventListener (см developer.mozilla.org/en-US/docs/Web/Events/beforeunload ) вместо этого, для кросс-браузерной совместимости и для предотвращения библиотечных проблем.
Жюльен Берубе
Я знаю, что это старый вопрос, но, если они действительно хотят предотвратить несколько сеансов, могут ли они использовать WebSockets?
Меган
1
@Sean - Ага ... если вы действительно хотите предотвратить несколько сеансов. WebSocket может осуществлять двустороннюю связь с отслеживанием состояния. Клиент (вероятно) не станет вдруг кем-то другим, пока подключен WebSocket, поэтому вы должны иметь возможность назначить токен этому пользователю и очистить его после закрытия сокета. Но он пытается обмануть ожидаемое поведение пользовательского агента, так что, вероятно, это плохой UX. Я могу придумать очень мало случаев, когда что-то подобное было бы уместным (может быть, онлайн-игра - чтобы кто-то не мог войти в систему как два когтя смерти 37 уровня ...).
Сет,
34

Вы не можете запретить пользователю обновляться, и вам не следует пытаться. Вы должны вернуться к тому, зачем вам это решение, в чем корень проблемы? Начните с этого и найдите другой способ решения проблемы. Возможно, вы подробно объяснили, почему, по вашему мнению, вам нужно это сделать, это поможет найти такое решение.

Нарушение основных функций браузера никогда не является хорошей идеей, более 99,999999999% Интернета работает и обновляется с помощью F5, это ожидание пользователя, которое вы не должны нарушать.

Ник Крейвер
источник
Проблема в том, что страница является приложением siebel. и когда пользователь находится в сеансе и нажимает кнопку «Обновить», создается новый сеанс, и приложение вылетает. поэтому мне нужно, чтобы пользователь не мог обновиться.
pankaj
20
@pankaj - это должно быть исправлено на сайте приложения и, например, в файлах cookie, чтобы пользователь делился сеансом между вкладками.
Ник Крейвер
9
Я не уверен, что вы отсюда идете. Бесчисленные сайты в Интернете предотвращают обновление браузера, если у вас грязная форма, предупреждая вас о том, что вы можете потерять свои изменения. Не уверен, почему это «нарушает фундаментальные функции браузера».
Siraris
1
@Siraris: Совершенно верно. Кроме того, я делаю частное приложение, которое пользователь должен иметь возможность использовать, даже если он не находится в своей частной сети. Поэтому я сохраняю все в хранилище браузера для автономного использования, но если он перезагружает страницу, все приложение исчезает. Может, это и не очень «обычно», но в современном ИТ-мире это будет становиться все больше и больше.
cslotty,
16

Хотя отключать клавишу F5 - не лучшая идея, вы можете сделать это в JQuery, как показано ниже.

<script type="text/javascript">
function disableF5(e) { if ((e.which || e.keyCode) == 116 || (e.which || e.keyCode) == 82) e.preventDefault(); };

$(document).ready(function(){
     $(document).on("keydown", disableF5);
});
</script>

Надеюсь, это поможет!

Нилеш
источник
28
А что насчет OSX, где CMD + R? Или мобильный, где есть кнопка для нажатия? Я не вижу в этом решения
ItalyPaleAle
14

В старые времена CGI у нас было много форм, которые запускали различные внутренние действия. Например, текстовые уведомления для групп, задания на печать, сбор данных и т. Д.

Если пользователь находился на странице, которая говорила «Подождите ... Выполняется ОГРОМНАЯ работа, которая может занять некоторое время». У них было больше шансов нажать REFRESH, и это было бы ПЛОХО!

ЗАЧЕМ? Потому что это приведет к увеличению количества медленных работ и, в конечном итоге, все затормозит.

Решение? Позвольте им сделать свою форму. Когда они отправляют свою форму ... Начните свою работу, а затем направьте их на другую страницу, которая говорит им подождать.

Где страница посередине фактически содержала данные формы, необходимые для запуска работы. Страница WAIT, однако, содержит уничтожение истории javascript. Таким образом, они могут ПЕРЕЗАГРУЗИТЬ эту страницу ожидания сколько угодно, и это никогда не вызовет запуск исходного задания в фоновом режиме, поскольку эта страница WAIT содержит только данные формы, необходимые для самого WAIT.

Надеюсь, это имеет смысл.

Функция уничтожения истории также помешала им щелкнуть НАЗАД и затем обновить.

Это было очень безупречно и отлично работало в течение МНОГИХ лет, пока некоммерческая организация была свернута.

Пример: ЗАПИСЬ ФОРМЫ - Соберите всю их информацию, и при отправке это запускает вашу бэкэнд-работу.

RESPONSE from form entry - возвращает HTML, который выполняет перенаправление на вашу статическую страницу ожидания и / или POST / GET в другую форму (страницу WAIT).

WAIT PAGE - содержит только данные FORM, относящиеся к странице ожидания, а также javascript для уничтожения самой последней истории. Например (-1 ИЛИ -2), чтобы уничтожить только самые последние страницы, но все же позволяет им вернуться к исходной странице ввода FORM.

Оказавшись на вашей странице WAIT, они могут нажимать REFRESH столько, сколько захотят, и это никогда не вызовет исходное задание FORM на бэкэнде. Вместо этого ваша страница WAIT должна включать само обновление по времени META, чтобы она всегда могла проверить статус своей работы. Когда их работа будет завершена, они будут перенаправлены со страницы ожидания туда, куда вы хотите.

Если они делают REFRESH вручную ... Они просто добавляют туда еще одну проверку статуса своей работы.

Надеюсь, это поможет. Удачи.

Тодд
источник
2
Вы не получили достаточной оценки за этот удивительный и информативный ответ. Спасибо!!
ShiningLight
3

Проблема №2 теперь может быть решена с помощью BroadcastAPI .

На данный момент он доступен только в Chrome, Firefox и Opera.

var bc = new BroadcastChannel('test_channel');

bc.onmessage = function (ev) { 
    if(ev.data && ev.data.url===window.location.href){
       alert('You cannot open the same page in 2 tabs');
    }
}

bc.postMessage(window.location.href);
RockLegend
источник
2

Число (2) возможно при использовании реализации сокета (например, websocket, socket.io и т. Д.) С настраиваемым пульсом для каждого сеанса, в котором участвует пользователь. Если пользователь пытается открыть другое окно, у вас есть проверка обработчика javascript с сервером, если все в порядке, а затем ответьте сообщением об ошибке.

Однако лучшим решением является синхронизация двух сеансов, если это возможно, как в документах Google.

поисковая оптимизация
источник