Запобігання будь-якій формі оновлення сторінки за допомогою jQuery / Javascript


93

Коли користувач перебуває на моїй сторінці, я не хочу, щоб він оновлював сторінку.

  1. У будь-який час користувач натискає F5кнопку або кнопку оновлення зверху. Він повинен отримати попередження

    Ви не можете оновити сторінку.

  2. Також якщо користувач відкриває нову вкладку і намагається отримати доступ до тієї ж URL-адреси на попередній вкладці, він повинен отримати попередження

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

У будь-якому разі я можу це зробити за допомогою JavaScript або jQuery? Пункт перший дуже важливий.


Ви можете виявити, використовуючи Broadcast Channel API ( developer.mozilla.org/en-US/docs/Web/API/Broadcast_Channel_API ), і надсилати повідомлення для зв'язку між вкладками. ТОМУ, використовуючи це, ви можете виявити декілька вкладок з однаковою адресою та заблокувати інші вкладки.
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
Я не впевнений, звідки ти тут. Незліченні веб-сайти в Інтернеті перешкоджають оновленню браузера, якщо у вас є брудна форма, попереджаючи вас про те, що ви можете втратити свої зміни. Не знаю, чому це "порушує основні функції браузера".
Сіраріс,

1
@ Сіраріс: Саме так. Крім того, я роблю приватну програму, якою користувач повинен користуватися, навіть коли він перебуває не в своїй приватній мережі. Тому я зберігаю все в сховищі браузера для використання в автономному режимі, але якщо він перезавантажує сторінку, вся програма зникає. Це може бути не дуже "звично", але в цьому сучасному ІТ-світі це стане дедалі більше.
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>

Сподіваюся, це допоможе!


27
Як щодо OSX, де це CMD + R? Або мобільний, де є кнопка для натискання? Я не бачу в цьому рішення
ItalyPaleAle

14

Ще в епоху CGI у нас було безліч форм, які запускали різні серверні дії. Такі як текстові повідомлення групам, завдання друку, обробка даних тощо.

Якщо користувач знаходився на сторінці, на якій було написано: "Будь ласка, почекайте ... Виконання ВЕЛИЧЕЗНОЇ роботи, яка може зайняти деякий час.". Вони, швидше за все, вдарять REFRESH, і це буде БАД!

ЧОМУ? Тому що це призведе до більш повільних робочих місць і врешті-решт завалить цілу справу.

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

Де сторінка посередині насправді містила дані форми, необхідні для початку роботи. Однак сторінка ЗАЧЕКАЙТЕ містить історію знищення історії JavaScript. Тому вони можуть ПЕРЕЗАГРУЗИТИ цю сторінку очікування все, що їм заманеться, і це ніколи не спричинить вихід оригінального завдання у фоновому режимі, оскільки ця сторінка WAIT містить лише дані форми, необхідні для самого WAIT.

Сподіваюся, що це має сенс.

Функція знищення історії також заважала їм натискати НАЗАД, а потім також оновлювати.

Це було дуже бездоганно і чудово працювало БАГАТО МНОГО років, поки некомерційна діяльність не була ліквідована.

Приклад: ФОРМОВИЙ ВХІД - Зберіть всю їхню інформацію, і після надсилання це ініціює ваше завдання.

ВІДПОВІДЬ із введення форми - повертає HTML, який виконує переспрямування на вашу статичну сторінку очікування та / або POST / GET в іншу форму (сторінку ЗАЧЕКАЙТЕ).

ЗАЧЕКАЙТЕ СТОРІНКУ - містить лише ФОРМАТНІ дані, що стосуються сторінки очікування, а також javascript для знищення найновішої історії. Як (-1 АБО -2), щоб знищити лише найновіші сторінки, але все одно дозволяє їм повернутися до початкової сторінки входу в ФОРМУ.

Потрапивши на вашу сторінку ЗАЧЕКАЙТЕ, вони можуть натискати кнопку ОЗНАВИТИ скільки завгодно, і це ніколи не породить оригінальну форму ФОРМИ у серверній системі. Натомість, ваша сторінка ЗАЧЕКАЙТЕ повинна охоплювати оновлене приурочене МЕТА, щоб вона завжди могла перевірити статус своєї роботи. Після завершення їх роботи вони перенаправляються подалі зі сторінки очікування, куди завгодно.

Якщо вони роблять ВОЗНАЧЕННЯ вручну ... Вони просто додають ще одну перевірку статусу своєї роботи.

Сподіваюся, що це допомагає. Удачі.


2
Ви не отримали достатньо кредитів за цю дивовижну та інформативну відповідь. Дякую!!
ShiningLight


2

Номер (2) можливий за допомогою реалізації сокета (наприклад, websocket, socket.io тощо) із користувацьким серцебиттям для кожного сеансу, в якому бере участь користувач. Якщо користувач намагається відкрити інше вікно, у вас є перевірка обробника javascript з сервером, якщо це нормально, а потім відповідь повідомленнями про помилку.

Однак кращим рішенням є синхронізація двох сеансів, якщо це можливо, як у google docs.


2

Проблему №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);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.