128

Once the user is on my page, I do not want him to refresh the page.

  1. Anytime, the user hits F5 or refresh button on top. He should get an alert saying

    You cannot refresh the page.

  2. Also if the user opens a new tab and tries to access the same url in prev tab he should get an alert

    You cannot open same page in 2 tabs

Anyway I can do this using JavaScript or jQuery? Point one is really important.

Community
  • 1
  • 1
pankaj
  • 1,291
  • 2
  • 9
  • 4
  • You can detect using Broadcast Channel API (https://developer.mozilla.org/en-US/docs/Web/API/Broadcast_Channel_API) And send msg's to communicate with between tabs. THUS, using this you can detect multiple tabs with same url And Block other tabs. – ezio4df Jan 23 '20 at 15:04

9 Answers9

250

#1 can be implemented via window.onbeforeunload.

For example:

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

The user will be prompted with the message, and given an option to stay on the page or continue on their way. This is becoming more common. Stack Overflow does this if you try to navigate away from a page while you are typing a post. You can't completely stop the user from reloading, but you can make it sound real scary if they do.

#2 is more or less impossible. Even if you tracked sessions and user logins, you still wouldn't be able to guarantee that you were detecting a second tab correctly. For example, maybe I have one window open, then close it. Now I open a new window. You would likely detect that as a second tab, even though I already closed the first one. Now your user can't access the first window because they closed it, and they can't access the second window because you're denying them.

In fact, my bank's online system tries real hard to do #2, and the situation described above happens all the time. I usually have to wait until the server-side session expires before I can use the banking system again.

Seth
  • 45,033
  • 10
  • 85
  • 120
  • 2
    Just a note that the onbeforeunload event is not available in versions of the Opera browser. – WillyCornbread Aug 20 '10 at 17:53
  • 2
    Is there a way to do something if user chooses to stay on the page. – hrishikeshp19 May 17 '12 at 18:35
  • 8
    Did the trick for me, although you should use window.addEventListener (see https://developer.mozilla.org/en-US/docs/Web/Events/beforeunload) instead, for cross-browser compatibility and to prevent library issues. – Julien Bérubé Jun 25 '14 at 14:29
  • I know this question is old but, if they _really_ wanted to prevent multiple sessions, could they use WebSockets? – Meghan Dec 21 '15 at 16:59
  • 1
    @Sean - Yup ... if you _really_ wanted to prevent multiple sessions. A WebSocket can do stateful, bidirectional communication. The client (probably) isn't going to suddenly become someone else while the WebSocket is connected, so you should be able to assign a token to that user, and clear it once the socket closes. But, it's hacking around the expected behavior of the user agent, so it's probably bad UX. I can think of extremely few cases where something like this would be appropriate (maybe an online game - to prevent someone from logging in as *two* level 37 death claws...). – Seth Dec 21 '15 at 19:04
  • How to call a function if user want to reload ? I mean if user clicks on confirm, I want to send a simple notification to server. How can we do with your solution? – gwthm.in Feb 19 '16 at 13:56
  • You could probably also find a way to do number two with session cookies or maybe a server-side language where you store the current page a user is on. Probably should avoid relying on ANY method of restricting user actions though since, as a user who doesnt like being restricted himself, users can always find ways around restrictions. eg: having the site open in multiple browsers. –  Apr 16 '18 at 09:47
  • This doesn't work on FireFox, also, Chrome doesn't include the `"Dude, are you sure you want to leave? Think of the kittens!";` message in the alert. But I upvoted anyway, since it almost works on Chrome. – Shayan Dec 09 '19 at 15:35
36

You can't prevent the user from refreshing, nor should you really be trying. You should go back to why you need this solution, what's the root problem here?. Start there and find a different way to go about solving the problem. Perhaps is you elaborated on why you think you need to do this it would help in finding such a solution.

Breaking fundamental browser features is never a good idea, over 99.999999999% of the internet works and refreshes with F5, this is an expectation of the user, one you shouldn't break.

Nick Craver
  • 623,446
  • 136
  • 1,297
  • 1,155
  • The problem is, that the page is a siebel application. and when a user is in a session and hits refresh, a new session gets created, and the app crashes. so I need the user to not be able to refresh. – pankaj Aug 19 '10 at 23:29
  • 23
    @pankaj - That should be fixed on the application site, and cookies for example so the user shares the session across tabs. – Nick Craver Aug 19 '10 at 23:30
  • 21
    I'm not sure where you're coming from here. Countless sites on the internet prevent a browser refresh if you have a form that is dirty, alerting you to the fact that you may lose your changes. Not sure why this is "breaking fundamental browser features". – Siraris Mar 31 '18 at 03:45
  • 1
    @Siraris: Exactly. Plus, I am making a private application that the user is supposed to be able to use even when he's not in his private network. So I store everything in the browser storage for offline usage, but if he reloads the page, the whole application is gone. It might not be very "usual", but in this modern IT world it will become more and more so. – cslotty Feb 10 '20 at 10:11
  • 3
    You shouldn't do it isn't an answer. This opinion may be valuable, but only as a postscript to a working solution. – Paweł Własiuk Oct 06 '21 at 08:51
  • This answer is broadly outdated (almost 12 years old). The web has evolved multiple times since 2010 and it is a valid UX reason to warn the user for potential loss of data in modern web applications. – MacK Nov 28 '22 at 12:28
22

Although its not a good idea to disable F5 key you can do it in JQuery as below.

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

Hope this will help!

Nilesh
  • 303
  • 2
  • 3
21

Back in the ole days of CGI we had many forms that would trigger various backend actions. Such as text notifications to groups, print jobs, farming of data, etc.

If the user was on a page that was saying "Please wait... Performing some HUGE job that could take some time.". They were more likely to hit REFRESH and this would be BAD!

WHY? Because it would trigger more slow jobs and eventually bog down the whole thing.

The solution? Allow them to do their form. When they submit their form... Start your job and then direct them to another page that tells them to wait.

Where the page in the middle actually held the form data that was needed to start the job. The WAIT page however contains a javascript history destroy. So they can RELOAD that wait page all they want and it will never trigger the original job to start in the background as that WAIT page only contains the form data needed for the WAIT itself.

Hope that makes sense.

The history destroy function also prevented them from clicking BACK and then refreshing as well.

It was very seamless and worked great for MANY MANY years until the non-profit was wound down.

Example: FORM ENTRY - Collect all their info and when submitted, this triggers your backend job.

RESPONSE from form entry - Returns HTML that performs a redirect to your static wait page and/or POST/GET to another form (the WAIT page).

WAIT PAGE - Only contains FORM data related to wait page as well as javascript to destroy the most recent history. Like (-1 OR -2) to only destroy the most recent pages, but still allows them to go back to their original FORM entry page.

Once they are at your WAIT page, they can click REFRESH as much as they want and it will never spawn the original FORM job on the backend. Instead, your WAIT page should embrace a META timed refresh itself so it can always check on the status of their job. When their job is completed, they are redirected away from the wait page to whereever you wish.

If they do manually REFRESH... They are simply adding one more check of their job status in there.

Hope that helps. Good luck.

Todd
  • 219
  • 2
  • 3
4

No, there isn't.

I'm pretty sure there is no way to intercept a click on the refresh button from JS, and even if there was, JS can be turned off.

You should probably step back from your X (preventing refreshing) and find a different solution to Y (whatever that might be).

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • As noted in another comment by @Paweł Własiuk: "You shouldn't do it isn't an answer. This opinion may be valuable, but only as a postscript to a working solution." – theUtherSide Dec 03 '21 at 23:33
4

Issue #2 now can be solved using BroadcastAPI.

At the moment it's only available in Chrome, Firefox, and 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
  • 497
  • 4
  • 9
2

Number (2) is possible by using a socket implementation (like websocket, socket.io, etc.) with a custom heartbeat for each session the user is engaged in. If a user attempts to open another window, you have a javascript handler check with the server if it's ok, and then respond with an error messages.

However, a better solution is to synchronize the two sessions if possible like in google docs.

seo
  • 1,959
  • 24
  • 18
0

According to MDN the best way to do this is to use the pagehide event, which is not 100% reliable but more reliable than the unload event that seems to be most widely recommended for this problem.

However, unlike the unload and beforeunload events, this event is compatible with the back/forward cache (bfcache), so adding a listener to this event will not prevent the page from being included in the bfcache... If you're specifically trying to detect page unload events, the pagehide event is the best option.

var url = window.location.pathname.toLowerCase();
if (url.includes("manufacturers/ford")) {
    window.addEventListener(
        "pagehide",
        (event) => {
            if (event.persisted) {
                // The page is about to close
                // Show a confirmation modal, return or similar
            }
        },
        false
    );
}
Hashim Aziz
  • 4,074
  • 5
  • 38
  • 68
-1

It is not advised, but if you want to completely prevent the user from refreshing the page in any way possible you can use:

setInterval(function(){
  window.location.reload();
  window.stop();
},100)

Not only will it prevent refreshing, but it will also prevent navigation.

EzWinz
  • 1
  • 1