Forum Moderators: coopster

Message Too Old, No Replies

duplicate form submissions

php duplicate form submissions

         

SeanF

11:35 am on Jan 22, 2022 (gmt 0)

5+ Year Member Top Contributors Of The Month



I have a name entry form where people enter names for name badges that get written to a MySQL database.

The problem is, if there is a short lag after hitting the "submit" button, it will duplicate the entries. ore even worse, if the user double clicks or triple clicks "submit" (even when the response time is "normal"), there will be double or triple the entries.

How can I avoid duplicate entries?

londrum

12:07 pm on Jan 22, 2022 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



you could check if the values already exist in the database before writing them

or you could try disabling the submit button through php or javascript as soon as the form is submitted

lucy24

4:46 pm on Jan 22, 2022 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



If it's any consolation, this problem is not unique to you. Several Well-Established Official Entities include a message saying not to click Submit again, or your entry/payment/letter will be posted twice.

w3dk

12:31 am on Jan 23, 2022 (gmt 0)

10+ Year Member Top Contributors Of The Month



The problem is, if there is a short lag after hitting the "submit" button, it will duplicate the entries


...and presumably they hit the submit button again during the "lag"?

disabling the submit button through php or javascript


That would need to be JavaScript, not PHP.

You could also try (server-side):

1. Generate a "unique token" as you send the form to the client.
2. Store the token in a "hidden" form field (that is later submitted with the form) and in a session variable (server-side, unique to the user).
3. A form submission is only successful when the token in the form submission matches the token in the session variable. At which point the session variable is cleared.
4. Subsequent form submissions are invalid since the session variable has already been cleared.

dstiles

9:32 am on Jan 23, 2022 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I have also seen dups when someone closes their browser on the submitted page and then re-opens the browser: that resubmits the form. Or simply presses the browser's Refresh button. I think I've got it covered now, similar to w3dk's solution.

Kendo

2:47 pm on Jan 23, 2022 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



When submitting, check if data already exists. If it exists, update that data, otherwise add a new entry. Should be standard procedure for every instance of submitting to a database.

phparion

6:21 pm on Feb 12, 2022 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



best way is to use a simple javascript to disable submit button once it is clicked, change its color to light grey and even additionally show a msg , form is already submitted, do not need to submit again, please wait...

if somehow you have to rely on only server side scripting then when you display form store a value in a session variable, once you submit form change it and then do not allow to submit again. e.g very roughly,

if($_SESSION['submitted'] == true) {
echo "form already submitted please wait";
} else {

echo "<input type=submit value='submit form'>";
}

where on the first time display session variable is set to false.

NickMNS

7:40 pm on Feb 12, 2022 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



All the answers above are wrong. Except for @w3dk which is almost correct.
That would need to be JavaScript, not PHP.

Yes!

Why?
Assuming no JS is used then, the request is made to the server using the standard HTML form submission functionality which loads a new page. If a new page loads, then there is no issue. So this is absolutely a Javascript issue, because this can only happen if the form is being prevented from loading a new page, as with event.preventDefault(). The fix is simple, when the onClick event is triggered one should set the submit button attribute to disabled=true. In addition as suggested by @phparion, you can change the color of the bottom. This can easily be done using only CSS by styling the class with a the :disabled pseudo-class*.

Now since the request is ajax, there is a good chance that one would want/expect the user to submit the form multiple times during their time on page. (Eg: trying different values). The solution above wont allow that, since the button would be disabled on the first click and not re-enabled after. The best solution is that case would be to use the javascript promises. Where the button is disabled onClick, at the same time as the request is made (Fetch as a promise), then (using Then) when the request's response returns, one sets the button back to disabled="false". Like that the button only becomes active after the new data is shown on the page.

Handling this issue server side is not addressing the root cause of the problem, and yes the server side solutions will prevent duplicate writes to the database, but it is not addressing the duplicate and thus wasteful requests to the server.

*info on disabled pseudo-class see here:
[developer.mozilla.org...]


Regarding W3dk's suggested solution.

You could also try (server-side):

1. Generate a "unique token" as you send the form to the client.
2. Store the token in a "hidden" form field (that is later submitted with the form) and in a session variable (server-side, unique to the user).
3. A form submission is only successful when the token in the form submission matches the token in the session variable. At which point the session variable is cleared.
4. Subsequent form submissions are invalid since the session variable has already been cleared.

It is good practice to implement this when your form is going to cause a write to your database. It ensures that the data is submitted from the actual page as opposed to simply by sending a request to the forms enpoint. This is particularly important if the user needs to be logged in to submit the form as it prevents CSRF attacks.

[cheatsheetseries.owasp.org...]

dstiles

10:55 am on Feb 14, 2022 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



That is not necessarily the case.

I use no or minimal JS as a matter of principle. Too many cases of buggy code (even mine) and in any case, as you say, not everyone (including me) enables JS as a matter of course.

Hence I build my forms to not use JS. I set it up so the that a submitted form is sent to the same page as it came from, in order that I can check that mandatory fields are filled in etc. If they haven't been, I display the form with an indication of missing fields. If it's correct I mail it and display a notice - on the same page - that the email has been sent. On page refresh, double-click on button, or browser re-open to form-submitted page the same page gives an "already submitted" message with a link to begin another form (they may want to submit an alteration of what they sent).

I have spent the past couple of years rebuilding old ASP sites as Apache/php - admittedly fairly simple sites - and only one site has JS to load in video clips.

londrum

11:13 am on Feb 14, 2022 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



that's what i do as well... submit the page back to itself, test all the data with PHP, and if it's good i show them what they submitted and totally remove the form. no need for any javascript.

although i do include a load of javascript on the original form as well, to try and stop spam submissions. i hard-code all the <inputs> and <submit> buttons so they're already disabled, and change the <form action=""> URL to a 404 page, and then change them all back with javascript. if they block javascript it's literally impossible to submit.
i know it's over the top but i got bored of spam

NickMNS

4:52 pm on Feb 14, 2022 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I'm not suggesting that you need to use JS to submit the form. What I'm saying is that this problem can only occur when using JS. Because even if you submit the form to the same page, the page refreshes providing the user with the feedback that it has be submitted, and I assume that once you've refreshed the page, when it is loaded again it provides some indication that the submit was successful or not.

And now the important part, since JS is used and no feedback is provided to the user, the server side-solutions will not stop the user from clicking the submit button multiple times and sending multiple requests to the server. And yes the server side solution will stop duplicate entries into the DB but that doesn't address the root or the problem.

londrum

10:37 pm on Feb 14, 2022 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



but if you send the page back to itself you can rewrite the HTML to whatever you want. so you just empty all the POST values and remove the submit button, or the entire form.

NickMNS

10:51 pm on Feb 14, 2022 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Yes, exactly so it's not a problem. The problem only occurs when JS is used to submit the form thus the only real solution is to fix the JS.

I suppose another solution would be to rewrite the entire page to submit the form and reload the entire page. It certainly wouldn't be my choice, but to each their own.

phparion

12:50 pm on Feb 25, 2022 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



@NickMNS: I don't know why are you insisting on JS and not sure why you called everybody wrong in the previous post. we are also programmers :D

have you worked with PHP-cURL? there are many critical solutions that use that, and you have to deal with many third party websites which block JS requests. so JS and libraries based on it can make fancy GUI but when it comes to the real application you would try to avoid using them.

hence for me posting page to itself and hiding submit button is a beautiful solution :)

NickMNS

3:12 pm on Feb 25, 2022 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I never said that the solutions proposed by others wont work or are bad. Moreover the programming language used for those solutions is not relevant. My point is that this issue is caused by JS and thus should to resolved by using JS on the client side. Any server side solution, may prevent the duplicate posts to the db, but it will not stop the duplicate requests to the server, which is the root cause of the problem.

there are many critical solutions that use that, and you have to deal with many third party websites which block JS requests.

I'm not sure what the relevance is of this statement. The only website that you "deal" with is your own, so I don't see how it matters whether other servers block JS. Are you talking about user and their browsers. This is true, the last time I checked my stats show those users accounted for less than 1% and most of those are likely bots or malicious actor trying to avoid detection. Those users also won't see ads. So I have decided, as a business decision, to ignore that 1% and instead provide an awesome user experience to 99% with features and functionalities that are only possible using client side JS. But that is me, and not relevant to issue at hand.

Side note: my older site uses progressive enhancement, such that users without JS still see some content but don't get full experience. But given 1% stat, on newer websites I don't even waste my time anymore. (The same goes for IE)