138

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.

1

8 Answers 8

262

#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[1] 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.


  1. The custom string return value for the onbeforeunload function has been deprecated on all browsers for quite a while (since 2013 or so). The function still works, but the custom message was only ever really used for spam and was removed.
Sign up to request clarification or add additional context in comments.

9 Comments

Just a note that the onbeforeunload event is not available in versions of the Opera browser.
Is there a way to do something if user chooses to stay on the page.
Did the trick for me, although you should use window.addEventListener (see developer.mozilla.org/en-US/docs/Web/Events/beforeunload) instead, for cross-browser compatibility and to prevent library issues.
I know this question is old but, if they really wanted to prevent multiple sessions, could they use WebSockets?
@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...).
|
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.

6 Comments

@pankaj - That should be fixed on the application site, and cookies for example so the user shares the session across tabs.
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: 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.
You shouldn't do it isn't an answer. This opinion may be valuable, but only as a postscript to a working solution.
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.
|
23

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.

1 Comment

You did not get enough credit for this amazing and informative answer. Thank you!!
21

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!

3 Comments

What about OSX, where it's CMD + R? Or mobile where there's a button to press? I don't see this as a solution
not sure about mac, any update on this? thanks @Nilesh
CMD + R for MacOS and CTRL + R for Windows can also be blocked in the same way, which is discussed here: stackoverflow.com/questions/46882116/…
5

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

Comments

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

1 Comment

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

Comments

0

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.

2 Comments

Prevent refreshing by periodic refresh ??
Actually found this snippet very useful, but kind of dangerous, or anyway annoying, unless paired with clearInterval as per developer.mozilla.org/en-US/docs/Web/API/Window/setInterval

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.