1

I have written the following Javascript code to catch F5 key press and prevent the user from refreshing:

(I understand this is not a good idea but I am stuck with this whether any one likes it or not. Also the question I ask pertains to why the script below does not work with Safari 4 but works for other browsers.)

var fn = function (e)
{

    if (!e)
        var e = window.event;

    var keycode = e.keyCode;
    if (e.which)
        keycode = e.which;

    var src = e.srcElement;
    if (e.target)
        src = e.target;    

    // 116 = F5
    if (116 == keycode)
    {
        // Firefox and other non IE browsers
        if (e.preventDefault)
        {
            e.preventDefault();
            e.stopPropagation();
        }
        // Internet Explorer
        else if (e.keyCode)
        {
            e.keyCode = 0;
            e.returnValue = false;
            e.cancelBubble = true;
        }

        return false;
    }
}

// Assign function to onkeydown event
document.onkeydown = fn;

The above code works perfectly for IE 6,7 and 8, from Firefox 2.0 onwards and also in Chrome.

However it does not work for Safari 4 for windows. Pressing the F5 key refreshes the document. The funny thing is that in Safari the code gets inside the if (e.preventDefault) part above but for some reason its not preventing the default action i.e. refreshing the page.

Is this a bug with Safari 4 or is there some Safari specific code I need to write?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
  • 14
    Why? I can simply press the reload icon and get the effect you're trying to prevent. No sane browser will ever let you have that level of control over its working and you shouldn't attempt to do this! – Joachim Sauer Sep 29 '09 at 11:55
  • 4
    Agreed. This smells horribly like the right-click blockers of times best forgotten... Fix your site so that refreshes don't break it rather than try to wrangle the multitude of browsers into doing your bidding. – Matthew Scharley Sep 29 '09 at 11:56
  • I know its a bad idea but thats the functionality the client wants. Tried to convince him against it but in vain. Also the page will be running in a "new window" opened from javascript without the toolbars and address bars so the users cant press the reload icon to refresh. –  Sep 29 '09 at 12:02
  • 1
    Are you then blocking ctrl-r too? That refreshes in atleast Firefox too. I can imagine that other browsers have their own custom refresh buttons. It's just not a viable thing to do. – Matthew Scharley Sep 29 '09 at 12:17
  • 2
    It's impossible functionality. For one thing, I have my browser (Opera) configured so that JS can't hide the toolbars or address bar, as I absolutely despise sites that try to do that. – MartW Sep 29 '09 at 12:18
  • 1
    'functionality' implies usefulness. I fail to see the usefulness of this, other than 'my client told me to' (which is valid in all but the worst cases, which this is) – Matthew Scharley Sep 29 '09 at 12:30
  • In my case: I have some vendor supplied code that allows a single user to take down all my app servers by adding 500+ portlets to their page and/or clicking the Add button repeatedly. The vendor will not fix it, but I do have the ability to alter the JSP myself. I have BlockUI in place, which prevents the user from clicking the Add button 100 times, but they can still click it once then hit F5 100 times. I know I can't prevent ALL forms of refresh, but if I can get an 80/20 here, I'd be very happy. I am not in a position to force management to replace the product we are using. – CodeChimp Jan 21 '14 at 15:10

6 Answers6

11

Never try anything that hinders a user's normal action with a browser. Even if you do this using javascript he can disable the script and then continue the page refresh.

If you need to prevent the action made on a refresh then handle it in server side.

rahul
  • 184,426
  • 49
  • 232
  • 263
  • 1
    That's all well and good to say, and I agree in principal, but sometime you don't have an option. For instance, in the case I am working on, I am working on Vendor-supplied code. I have access to the JSP, but nothing else, and my employer is currently on an old version, so getting the vendor to change code is not possible (besides, the vendor is retarded, and probably couldn't fix it anyhow). Meanwhile, I have a support issue that requires me to disable refresh for users. Most of my users wouldn't even know how to turn off JS. – CodeChimp Jan 21 '14 at 14:59
6

It seems like you are trying to obstruct the user from doing something that your code cannot handle easily, e.g. stopping them 'purchasing item X' twice by hitting refresh, or hitting your site too often by holding F5 to annoy you.

I'd suggest other solutions such as cookies/state management or blocking client IPs if you are preventing abuse.

JBRWilkinson
  • 4,821
  • 1
  • 24
  • 36
6

To the people who are saying, "don't do this": You aren't helping. There is ALWAYS a side case where a rule of thumb must be broken.

For example, the client I'm working with has a system that has a major piece of their testing application built off of a second browser window, which goes full screen, no toolbars, bookmarks, or any other window options, and disables all keys that aren't directly affected by the testing environment. In this case, it is valuable to the user, who is likely someone of low technical skill, to be able to take the test without inadvertently hitting F5 and reloading a large, client-side series of questions with all of their previous answers erased. The questions are client side because preloading allows the test to be run on a low-bandwidth connection, like those found in the third world.

From what I can tell of this Safari-only issue (Chrome, another Webkit-based browser, doesn't have this problem), even the alert box will not keep the browser from refreshing. The alert shows, then the page refreshes normally.

Nothing I've tried seems to block the key. I have read that this is considered a defect with Safari, and that a certain build number of Safari should contain a fix, but as of the time I'm writing this, this hasn't been implemented in the most recent version of Safari for Windows. I've tested this on the Mac, and it seems to be fixed on that platform.

WRast
  • 61
  • 1
  • 1
4

+1 to everyone else saying “don't do this”. It's just not at all feasible. There are many other ways of refreshing the page... on my browser at least: the toolbar button*; ctrl-R; right-click-reload; ctrl-T to get a tab bar then right-click-on-tab-reload; and so on. Tell your client it's impossible and get on with something actually useful.

*: trying to hide the browser chrome is also not allowed by my browser, because it's a really bad idea. You are opening yourself up to phishing attacks by eliding the essential indicators that tell the user that they are really on your site.

bobince
  • 528,062
  • 107
  • 651
  • 834
0

Yes, it appears to be a bug with Safari 4 Windows. You cannot stop CTRL+F either.

However, opening an alert stops it, but that is a rough trade off.

jedierikb
  • 12,752
  • 22
  • 95
  • 166
-1

I had a logic to handle the F5 similar to the question.I am displaying a confirm box which asks "Data you have entered may not be saved?".If the the user click Ok, page should reload and if click Cancel, page need to retain as it is. But only in safari "Cancel" click also reload the page. I have tested in Safari 5.1.7.