Perhaps a common problem, but I'm pondering about the best solution for this:
1. I have a simple shop. If people click on "add product X", they are taken to a new page with a shopping cart (now containing one item X).
2. If they hit F5 or click refresh on the shopping cart page, I don't want *another* X being added to their cart.
3. However, if they go back to the initial shop page, and explicitly click on "add product X" again, then I *do* want another X to be added.
My problem: on the shopping cart page, how do I distinguish between a previous POST request being re-sent due to refresh/F5, and a new one from a real click?
I thought about including a random ID (as hidden field) along with the "add product X" form post, and on the shopping cart I only process items if the ID wasn't already processed before (storing processed IDs in their session or something). However, I think if the customer hits 'back' from the shopping cart page, going back to the first page, most likely they will get the first version from cache, with the same random ID again, which would cause a second "add X" click to be ignored.
What do you think guys??
Avoid duplicate form submitting?
Moderator: General Moderators
Re: Avoid duplicate form submitting?
It's one of those problems with a simple solution. 
Assign every session a random unique token. Include this token on each form as a hidden input. When the form is submitted, it will compare the token in the form with the one in their session, if it's a match, continue the process. Once it is a match, you will need to regenerate the random token in the session array.
This should also protect you from cross-site request forgeries.
--- Another method
You could also just check the HTTP referrer and if it equals the form page, then don't process the form. This method won't work if you are including the form and the script in the same file.
Assign every session a random unique token. Include this token on each form as a hidden input. When the form is submitted, it will compare the token in the form with the one in their session, if it's a match, continue the process. Once it is a match, you will need to regenerate the random token in the session array.
This should also protect you from cross-site request forgeries.
--- Another method
You could also just check the HTTP referrer and if it equals the form page, then don't process the form. This method won't work if you are including the form and the script in the same file.
Re: Avoid duplicate form submitting?
Thanks, but about this:
Note that if they click 'back' (in their browser), it will likely not reload the actual .php again, but rather show the cached result from last time (with the same initial token hidden in the form).
(besides, sending referrer info can also be disabled in browsers, although I don't know if many people actually do this)
I don't see how this fixes point 3 mentioned above?AlanG wrote:Assign every session a random unique token. Include this token on each form as a hidden input. When the form is submitted, it will compare the token in the form with the one in their session, if it's a match, continue the process. Once it is a match, you will need to regenerate the random token in the session array.
Note that if they click 'back' (in their browser), it will likely not reload the actual .php again, but rather show the cached result from last time (with the same initial token hidden in the form).
In this case, unfortunately I amYou could also just check the HTTP referrer and if it equals the form page, then don't process the form. This method won't work if you are including the form and the script in the same file.
(besides, sending referrer info can also be disabled in browsers, although I don't know if many people actually do this)
Re: Avoid duplicate form submitting?
But, if you generate a new token on each page (and the page that the form submits to), then the token from the last page reloaded from cache would not be correct.Note that if they click 'back' (in their browser), it will likely not reload the actual .php again, but rather show the cached result from last time (with the same initial token hidden in the form).
I think this is what AlanG means...
Also, most (if not all) browsers display a confirmation message when resubmitting POST data...so the user should be aware that they're adding another item to the cart.
Re: Avoid duplicate form submitting?
Sorry, I thought you meant that if they went back using a link you provided or something. A refresh will cause the browser's message to appear regardless of whether you use a token or not, and the previous page is probably going to be a cached one.
So the options (off the top of my head) are...
i) Deal with it
You can display a message to the user (when they hit the back button and attempt to reload the previous form) notifying them that they will have to refresh the page? You could possibly detect it yourself and change the value of the hidden input field using Javascript.
ii) Disable cache on the previous page
Self explanatory.
iii) Manipulate the browser's back button.
Maybe you can detect when it is clicked and cause it to load the target page as opposed to reload. Google the 'onbeforeunload' javascript event handler.
So the options (off the top of my head) are...
i) Deal with it
You can display a message to the user (when they hit the back button and attempt to reload the previous form) notifying them that they will have to refresh the page? You could possibly detect it yourself and change the value of the hidden input field using Javascript.
ii) Disable cache on the previous page
Self explanatory.
iii) Manipulate the browser's back button.
Maybe you can detect when it is clicked and cause it to load the target page as opposed to reload. Google the 'onbeforeunload' javascript event handler.