How do you prevent a form resubmission using the back browser button?
This problem came up for me on some old legacy code, a shopping cart. A user would go through the view cart form, the shipping section and then click the checkout button. If the user would then click on the browser back button, the same checkout form and checkout button would display. The user could then click the checkout button again and reorder, submitting the exact same information.
There's all kinds of things wrong with this scenario but I will just offer a couple of solutions.
First off the best way to prevent this browser back button resubmission is to have a 3 template process.
- The form template
- The action template where the form is processed, query inserts, cfmail, etc.
- The redirection page or thank you page.
The end of your action template would have a redirection to the thank you page. After all the code to process the submitted form variables, down at the bottom, have a to the thank you template. When the user attempts to hit the back browser button, the page will have expired. It would be best if you had code accepting submissions only from the original form template, with a redirection to a 404 or some other page.
In my case, I didn't want to rewrite a whole bunch of existing and mostly operating code, so I came up with another solution. The code with which I was working had the thank you template included in the action template. It could not easily have been broken out, there were too many variables set within the action template that were required within the thank you page. The thank you template was a complete order review for the transaction.
The minimalistic approach that I took was to create and add this bit of code:
1<!--- to prevent resubmission using browser back button --->
3 <cfset StructDelete(session,"submittedAlready") />
4 <cflocation url="viewCart.cfm" addtoken="false" />
6 <cfset session.submittedAlready = "true" />
Let's go over this snippet starting with the 5th line.
1<cfset session.submittedAlready = "true" />
We are setting a session variable that tells us the form has been submitted and processed already. If the user attempts to go back using the browser back button and resubmit the same form, we catch it with our check for the existence of that specific session variable.
If it has been submitted, we redirect, in this case, back to their empty cart. You could redirect to a notification of attempted resubmission too. That's up to you.
I threw in the StructDelete, deleting the existence of the session variable because:
- We don't need the session variable anymore, and
- It would block the user from using the form again. The user may have to go back and order something else they had forgotten, or submit different information using the same form. If we do not clear out this session variable, it will prevent them from filling out the form with new information.
One more thing. Where do we place this code?
It goes on your action template before you do any form processing.
And there you have the quick and easy way to prevent users browsing backwards to the same form and resubmitting the same information – repeating submissions.