0

Is there a way to bind a jQuery event to pop off after a visitor holds a button for more than, say, 3 seconds? In this case I'd like to do something after a user holds f5 for 3 seconds.

I've found a solution that prevents the refresh when user presses f5 here:

Disable F5 and browser refresh using javascript

However, this isn't quite what I'm looking for as I'd like to allow my users to refresh pages but prevent them from placing a rock on the f5 button so to speak (it's an online game where you can do tasks by refreshing the page).

Is what I'm trying to do even possible?

EDIT: I am looking for a short-term, quick, client-side fix. The server side of things will be solved later on.

Community
  • 1
  • 1
sveti petar
  • 3,637
  • 13
  • 67
  • 144

2 Answers2

7

This is the kind of problem you really need to solve server side. If the task can be accomplished by refreshing the page, then it can be accomplished by a bot or a line-or-two of script that disables your check. Doing this client side won't really help you.

All you need to do in that case is on the users session, track the last time that action X was performed, and don't perform it again unless more than Y seconds have passed, and tell the user off for trying to do it too fast.

Edit: As a quick hack, what you could possibly do is configure your webserver to supply a cache-control header in the response for affected scripts with a value set to have the content expire in Y seconds. This may (emphasis on may, test this properly first!) prevent the client from re-requesting the page on a normal 'F5', however a force refresh (ctrl+f5 in some browsers) won't be affected by this.

Although again if the issue is that users are exploiting this issue, fixing it client side won't work for very long and users will quickly discover another way around.

PhonicUK
  • 13,486
  • 4
  • 43
  • 62
  • 5
    +1 It **can** be done client-side (using a cookie or local storage), but what if a dedicated cheat bypasses the browser entirely and just fires off raw HTTP requests? Server-side is the only way. – T.J. Crowder Feb 13 '13 at 14:32
  • Can't +1 this answer hard enough. There's no problem in running some client-side script as an optimisation, but you *must* solve this problem at your server, because **any** HTTP client can talk to it, not just browsers. – Paul Turner Feb 13 '13 at 14:34
  • I understand, but there are a lot of actions on a lot of different pages, which a few different developers worked on. I didn't code any of this, I was just asked to apply a quick client-side fix for now. That's why I'm asking if it's possible. – sveti petar Feb 13 '13 at 14:34
  • @robert: Just posted a client-side alternative answer. But again, really, this isn't a client-side problem. :-) – T.J. Crowder Feb 13 '13 at 14:40
  • 3
    It's understandable if the orders are coming from above, but it's pretty much equal to someone asking you to paint a picture of a lock on a door as a quick fix to stop burglaries. – JJJ Feb 13 '13 at 14:40
  • 1
    @Juhana Indeed. What's ironic is that I'm a server-side developer, I was asked to do this by a friend because the whole gamesite is a mess and he just wants a quick fix for now because they're straining his server with the constant refreshing. – sveti petar Feb 13 '13 at 14:43
  • @robert: +1 for the irony. :-) – T.J. Crowder Feb 13 '13 at 14:43
1

PhonicUK's answer (do it server side) is the only correct way to handle this. But you said in a comment on that answer:

I was just asked to apply a quick client-side fix for now. That's why I'm asking if it's possible.

It's possible to do something that will get bypassed, like this (here I'm assuming you use a jQuery cookie plugin):

(function($) {

    $(document).on("keydown", function(e) {
        var lastRefresh, now;

        if (e.which == 116) {
            now = new Date().getTime();
            lastRefresh = $.cookie("lastRefresh");
            if (lastRefresh && (now - parseInt(lastRefresh, 10)) < 3000) {
                e.preventDefault();
            }
            $.cookie("lastRefresh", now);
        }
    });

})(jQuery);

Again, though, the users will find a way around it.

Be sure to run the script through the Closure compiler or a really good obfuscator. :-)

Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875