Ngăn chặn mọi hình thức làm mới trang bằng jQuery / Javascript


92

Khi người dùng ở trên trang của tôi, tôi không muốn anh ta làm mới trang.

  1. Bất cứ lúc nào, người dùng nhấn F5hoặc nút làm mới ở trên cùng. Anh ấy sẽ nhận được một câu nói cảnh báo

    Bạn không thể làm mới trang.

  2. Ngoài ra, nếu người dùng mở một tab mới và cố gắng truy cập vào cùng một url trong tab trước, anh ta sẽ nhận được cảnh báo

    Bạn không thể mở cùng một trang trong 2 tab

Dù sao tôi có thể làm điều này bằng cách sử dụng JavaScript hoặc jQuery? Điểm một là thực sự quan trọng.


Bạn có thể phát hiện bằng cách sử dụng API kênh phát sóng ( developer.mozilla.org/en-US/docs/Web/API/Broadcast_Channel_API ) và gửi tin nhắn để giao tiếp giữa các tab. VẬY, bằng cách sử dụng này, bạn có thể phát hiện nhiều tab có cùng url và Chặn các tab khác.
aXuser264

Câu trả lời:


191

# 1 có thể được thực hiện thông qua window.onbeforeunload.

Ví dụ:

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

Người dùng sẽ được nhắc với thông báo và được cung cấp tùy chọn để ở lại trang hoặc tiếp tục theo cách của họ. Điều này đang trở nên phổ biến hơn. Stack Overflow thực hiện điều này nếu bạn cố gắng điều hướng khỏi một trang trong khi bạn đang nhập một bài đăng. Bạn không thể ngăn hoàn toàn người dùng tải lại, nhưng bạn có thể làm cho nó nghe thật đáng sợ nếu họ làm vậy.

# 2 là ít nhiều không thể. Ngay cả khi bạn đã theo dõi các phiên và thông tin đăng nhập của người dùng, bạn vẫn không thể đảm bảo rằng bạn đang phát hiện tab thứ hai một cách chính xác. Ví dụ, có thể tôi đang mở một cửa sổ, sau đó đóng nó lại. Bây giờ tôi mở một cửa sổ mới. Bạn có thể sẽ phát hiện ra nó như một tab thứ hai, mặc dù tôi đã đóng tab đầu tiên. Giờ đây, người dùng của bạn không thể truy cập cửa sổ đầu tiên vì họ đã đóng nó và họ không thể truy cập cửa sổ thứ hai vì bạn đang từ chối họ.

Trên thực tế, hệ thống trực tuyến của ngân hàng của tôi rất cố gắng để thực hiện điều thứ 2 và tình huống được mô tả ở trên luôn xảy ra. Tôi thường phải đợi cho đến khi phiên phía máy chủ hết hạn trước khi có thể sử dụng lại hệ thống ngân hàng.


1
Chỉ cần lưu ý rằng sự kiện onbeforeunload không có sẵn trong các phiên bản của trình duyệt Opera.
WillyCornbread

1
Có cách nào để thực hiện điều gì đó nếu người dùng chọn ở lại trang không.
riship89

5
Có một mẹo nhỏ đối với tôi, mặc dù bạn nên sử dụng window.addEventListener (xem developer.mozilla.org/en-US/docs/Web/Events/beforeunload ) để tương thích với nhiều trình duyệt và để ngăn chặn các vấn đề về thư viện.
Julien Bérubé

Tôi biết câu hỏi này đã cũ nhưng nếu họ thực sự muốn ngăn nhiều phiên, họ có thể sử dụng WebSockets không?
Meghan

1
@Sean - Yup ... nếu bạn thực sự muốn ngăn nhiều phiên. Một WebSocket có thể thực hiện giao tiếp hai chiều, trạng thái. Máy khách (có thể) sẽ không đột nhiên trở thành người khác trong khi WebSocket được kết nối, vì vậy bạn có thể gán mã thông báo cho người dùng đó và xóa mã này khi ổ cắm đóng. Tuy nhiên, nó tấn công xung quanh hành vi mong đợi của tác nhân người dùng, vì vậy nó có thể là trải nghiệm người dùng tồi. Tôi có thể nghĩ ra rất ít trường hợp mà thứ gì đó như thế này sẽ phù hợp (có thể là một trò chơi trực tuyến - để ngăn ai đó đăng nhập với tư cách là hai móng vuốt tử thần cấp 37 ...).
Seth

35

Bạn không thể ngăn người dùng làm mới, bạn cũng không nên thực sự cố gắng. Bạn nên quay lại lý do tại sao bạn cần giải pháp này, vấn đề gốc rễ ở đây là gì ?. Bắt đầu từ đó và tìm một cách khác để giải quyết vấn đề. Có lẽ bạn đã giải thích cặn kẽ về lý do tại sao bạn nghĩ rằng bạn cần làm điều này, nó sẽ giúp ích trong việc tìm ra giải pháp như vậy.

Phá vỡ các tính năng cơ bản của trình duyệt không bao giờ là một ý tưởng hay, hơn 99,999999999% internet hoạt động và làm mới với F5, đây là kỳ vọng của người dùng, bạn không nên phá vỡ.


Vấn đề là trang đó là một ứng dụng siebel. và khi người dùng đang ở trong một phiên và nhấn làm mới, một phiên mới sẽ được tạo và ứng dụng gặp sự cố. vì vậy tôi cần người dùng không thể làm mới.
pankaj

20
@pankaj - Điều đó sẽ được khắc phục trên trang web ứng dụng và cookie chẳng hạn để người dùng chia sẻ phiên trên các tab.
Nick Craver

9
Tôi không chắc bạn đến từ đâu. Vô số trang web trên internet ngăn chặn việc làm mới trình duyệt nếu bạn có biểu mẫu bị bẩn, cảnh báo cho bạn biết rằng bạn có thể mất các thay đổi của mình. Không chắc tại sao điều này là "phá vỡ các tính năng cơ bản của trình duyệt".
Siraris,

1
@Siraris: Chính xác. Ngoài ra, tôi đang tạo một ứng dụng riêng tư mà người dùng được cho là có thể sử dụng ngay cả khi anh ta không ở trong mạng riêng của mình. Vì vậy, tôi lưu trữ mọi thứ trong bộ nhớ của trình duyệt để sử dụng ngoại tuyến, nhưng nếu anh ấy tải lại trang, toàn bộ ứng dụng sẽ biến mất. Nó có thể không "bình thường" lắm, nhưng trong thế giới CNTT hiện đại này, nó sẽ ngày càng trở nên như vậy.
cslotty

16

Mặc dù tắt phím F5 không phải là một ý kiến ​​hay, bạn có thể thực hiện nó trong JQuery như bên dưới.

<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>

Hy vọng điều này sẽ giúp ích!


27
Còn OSX thì sao, nó là CMD + R? Hoặc điện thoại di động nơi có một nút để nhấn? Tôi không xem đây là một giải pháp
ItalyPaleAle,

14

Quay lại những ngày đầu của CGI, chúng ta có nhiều hình thức sẽ kích hoạt các hành động phụ trợ khác nhau. Chẳng hạn như thông báo văn bản cho các nhóm, lệnh in, quản lý dữ liệu, v.v.

Nếu người dùng đang ở trên một trang có nội dung "Vui lòng đợi ... Đang thực hiện một số công việc LỚN có thể mất một chút thời gian.". Họ có nhiều khả năng nhấn REFRESH và điều này sẽ XẤU!

TẠI SAO? Bởi vì nó sẽ kích hoạt nhiều công việc chậm hơn và cuối cùng là sa lầy toàn bộ.

Giải pháp? Cho phép họ làm theo mẫu của họ. Khi họ gửi biểu mẫu ... Hãy bắt đầu công việc của bạn và sau đó hướng họ đến một trang khác yêu cầu họ đợi.

Nơi trang ở giữa thực sự chứa dữ liệu biểu mẫu cần thiết để bắt đầu công việc. Tuy nhiên, trang CHỜ chứa một hủy lịch sử javascript. Vì vậy, họ có thể RELOAD trang chờ đó tất cả những gì họ muốn và nó sẽ không bao giờ kích hoạt công việc ban đầu để bắt đầu ở chế độ nền vì trang WAIT đó chỉ chứa dữ liệu biểu mẫu cần thiết cho chính WAIT.

Hy vọng điều đó có ý nghĩa.

Chức năng hủy lịch sử cũng ngăn họ nhấp vào QUAY LẠI và sau đó làm mới.

Nó rất liền mạch và hoạt động hiệu quả trong NHIỀU năm cho đến khi tổ chức phi lợi nhuận bị loại bỏ.

Ví dụ: NHẬP MẪU - Thu thập tất cả thông tin của họ và khi được gửi, điều này sẽ kích hoạt công việc phụ trợ của bạn.

RESPONSE từ mục nhập biểu mẫu - Trả về HTML thực hiện chuyển hướng đến trang chờ tĩnh của bạn và / hoặc ĐĂNG / NHẬN đến một biểu mẫu khác (trang CHỜ).

TRANG CHỜ - Chỉ chứa dữ liệu MẪU liên quan đến trang chờ cũng như javascript để hủy lịch sử gần đây nhất. Giống như (-1 HOẶC -2) để chỉ hủy các trang gần đây nhất, nhưng vẫn cho phép chúng quay lại trang mục nhập MẪU ban đầu của chúng.

Khi họ ở trang CHỜ của bạn, họ có thể nhấp vào LÀM MỚI bao nhiêu tùy thích và nó sẽ không bao giờ xuất hiện công việc MẪU ban đầu trên chương trình phụ trợ. Thay vào đó, trang WAIT của bạn nên tự làm mới theo thời gian META để nó luôn có thể kiểm tra trạng thái công việc của họ. Khi công việc của họ hoàn thành, họ được chuyển hướng khỏi trang chờ đến bất cứ nơi nào bạn muốn.

Nếu họ làm lại thủ công ... Họ chỉ cần thêm một lần kiểm tra trạng thái công việc của họ trong đó.

Hy vọng rằng sẽ giúp. Chúc may mắn.


2
Bạn đã không nhận được đủ tín dụng cho câu trả lời tuyệt vời và nhiều thông tin này. Cảm ơn bạn!!
ShiningLight


2

Số (2) có thể thực hiện được bằng cách sử dụng triển khai socket (như websocket, socket.io, v.v.) với nhịp tim tùy chỉnh cho mỗi phiên mà người dùng tham gia. Nếu người dùng cố gắng mở một cửa sổ khác, bạn phải kiểm tra trình xử lý javascript với máy chủ nếu nó ổn, và sau đó trả lời bằng một thông báo lỗi.

Tuy nhiên, một giải pháp tốt hơn là đồng bộ hóa hai phiên nếu có thể như trong tài liệu google.


2

Vấn đề số 2 hiện có thể được giải quyết bằng BroadcastAPI .

Hiện tại, nó chỉ có sẵn trong Chrome, Firefox và 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);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.