[Vuejs]-How to prevent vote multiple/fast clicking in Vue exploit?

0👍

Since you are only allowing one vote (or that is what i understand) i would not increase the upvotes directly but make kind of a system with booleans kind of like this:

<button v-on:click="activateUpVote">UpVote</button>
<button v-on:click="activateDownVote">DownVote</button>
.
.
.
data(){
  return{
    upVote: false,
    downVote: false,
    hasVoted: false
  }
},
methods: {
  activateUpVote(){
    this.upVote = !this.upVote
    if(this.upVote && (!this.hasVoted || this.downVote)){
      this.downVote = false
      this.hasVoted = true
      this.vote('/votedown/'+this.question, this.votes + 1)
    }else{
      this.hasVoted = false
    }
  },
  //downVote same as above but the other way around except for the hasVoted part          
  vote(route, votes) {
    axios.post(route)
        .then(response => votes)
        .catch(response => console.log(response.data));
    },
}

0👍

Try this solution

Template

    <div>
        <button @click="voteUp">UpVote</button>
        <button @click="voteDown">DownVote</button>
    </div>

Data

    data: () => {
        return {
            timer: null,
            interval: 200
        }
    },

Methods

    methods: {
        voteUp: function () {
            clearTimeout(this.timer);
            this.timer = setTimeout(() => {
                console.log('up vote')
                // your action
            }, this.interval);
        },

        voteDown: function () {
            clearTimeout(this.timer);
            this.timer = setTimeout(() => {
                console.log('down vote')
                // your action
            }, this.interval);
        }
    }

I’m using setTimeout and clearTimeout in the methods. This will prevent consecutive actions on the buttons. Continuous clicks will trigger only one action. The time between each click can be controlled using the interval value in the data.

0👍

You should disable the button after it was pressed and enabled it again after you get a response. This is usable for any button that you wan’t to disable spamming.

In your data add a boolean for each button

data () {
  return {
    //other data
    upVoteInAir: false
  }
}

then bind your button based on the flag

<button :disabled="upVoteInAir">Up</button>

update the flag based on the http request

methods: {
    voteUp(question) {
        this.upVoteInAir = true
        axios.post('/voteup/'+question)
            .then(response => this.isVoted = true, this.votes = this.votes + 1,         this.upVoteInAir = false)
            .catch(response => console.log(response.data),         this.upVoteInAir = false);
    },
}

Leave a comment